private void SimulateTEM(ref ProgressReporter progressReporter, ref Stopwatch timer, ref CancellationToken ct) { mCL.initialiseCTEMSimulation(CurrentResolution, SimRegion.xStart, SimRegion.yStart, SimRegion.xFinish, SimRegion.yFinish, isFull3D, isFD, dz, integrals); // Reset atoms incase TDS has been used mCL.sortStructure(false); // Use Background worker to progress through each step var NumberOfSlices = 0; mCL.getNumberSlices(ref NumberOfSlices, isFD); // Seperate into setup, loop over slices and final steps to allow for progress reporting. for (var i = 1; i <= NumberOfSlices; i++) { if (ct.IsCancellationRequested == true) { break; } timer.Start(); mCL.doMultisliceStep(i, NumberOfSlices); timer.Stop(); var mem = mCL.getCLMemoryUsed(); // Report progress of the work. float ms = timer.ElapsedMilliseconds; progressReporter.ReportProgress((val) => { CancelButton.IsEnabled = true; UI_UpdateSimulationProgress(ms, NumberOfSlices, 1, 1, i, mem); }, i); } }
private void SimulateCBED(int TDSruns, ref ProgressReporter progressReporter, ref Stopwatch timer, ref CancellationToken ct) { mCL.initialiseSTEMSimulation(CurrentResolution, SimRegion.xStart, SimRegion.yStart, SimRegion.xFinish, SimRegion.yFinish, isFull3D, isFD, dz, integrals, 1); //int posX = CurrentResolution / 2; //int posY = CurrentResolution / 2; var posx = (CBED_xpos - SimRegion.xStart) / pixelScale; var posy = (CBED_ypos - SimRegion.yStart) / pixelScale; // Use Background worker to progress through each step var NumberOfSlices = 0; mCL.getNumberSlices(ref NumberOfSlices, isFD); // Seperate into setup, loop over slices and final steps to allow for progress reporting. var runs = 1; if (doTDS_CBED) { runs = TDSruns; } TDSImage = new float[CurrentResolution * CurrentResolution]; for (var j = 0; j < runs; j++) { mCL.sortStructure(doTDS_CBED); mCL.initialiseSTEMWaveFunction(posx, posy, 1); for (var i = 1; i <= NumberOfSlices; i++) { if (ct.IsCancellationRequested == true) { break; } timer.Start(); mCL.doMultisliceStep(i, NumberOfSlices); timer.Stop(); var mem = mCL.getCLMemoryUsed(); float ms = timer.ElapsedMilliseconds; // Report progress of the work. progressReporter.ReportProgress((val) => { CancelButton.IsEnabled = true; // Note: code passed to "ReportProgress" can access UI elements freely. UI_UpdateSimulationProgress(ms, NumberOfSlices, runs, j, i, mem); }, i); } // After a complete run if TDS need to sum up the DIFF... //mCL.AddTDSDiffImage(TDSImage, CurrentResolution); mCL.getDiffImage(TDSImage, CurrentResolution); // Sum it in C++ also for the stem pixel measurement... //mCL.AddTDS(); if (ct.IsCancellationRequested == true) { break; } progressReporter.ReportProgress((val) => { CancelButton.IsEnabled = false; UpdateTDSImage(); }, j); } }
private void SimulateSTEM(int TDSruns, ref ProgressReporter progressReporter, ref Stopwatch timer, ref CancellationToken ct, int multistem) { LockedDetectors = Detectors; LockedArea = STEMRegion; foreach (DetectorItem dt in LockedDetectors) { dt.PixelScaleX = LockedArea.getxInterval; dt.PixelScaleY = LockedArea.getyInterval; dt.SetPositionReadoutElements(ref LeftXCoord, ref LeftYCoord); } if (LockedDetectors.Count == 0) { var result = MessageBox.Show("No Detectors Have Been Set", "", MessageBoxButton.OK, MessageBoxImage.Error); return; } int numPix = LockedArea.xPixels * LockedArea.yPixels; int pix = 0; foreach (DetectorItem i in LockedDetectors) { i.ImageData = new float[numPix]; i.Min = float.MaxValue; i.Max = float.MinValue; } int runs = 1; if (doTDS_STEM) { runs = TDSruns; } int totalPix = numPix * runs; mCL.initialiseSTEMSimulation(CurrentResolution, SimRegion.xStart, SimRegion.yStart, SimRegion.xFinish, SimRegion.yFinish, isFull3D, isFD, dz, integrals, multistem); float xInterval = LockedArea.getxInterval; float yInterval = LockedArea.getyInterval; //List<float[]> TDSImages = new List<float[]>(); List <float> fCoordxs = new List <float>(); List <Tuple <Int32, Int32> > Pixels = new List <Tuple <Int32, Int32> >(); for (int posY = 0; posY < LockedArea.yPixels; posY++) { for (int posX = 0; posX < LockedArea.xPixels; posX++) { Pixels.Add(new Tuple <Int32, Int32>(posX, posY)); } } for (int j = 0; j < runs; j++) { Shuffler.Shuffle <Tuple <Int32, Int32> >(Pixels); // Reset image contrast limits for every run.... foreach (DetectorItem i in LockedDetectors) { i.Min = float.MaxValue; i.Max = float.MinValue; } //for (int posY = 0; posY < LockedArea.yPixels * LockedArea.xPixels; posY+=multistem) // won't loop over end? //{ int posY = 0; int conPix = multistem; // numPix // multistem while (posY < numPix) { mCL.sortStructure(doTDS_STEM); int thisPosY = posY; if (posY + multistem > numPix && posY + multistem - numPix + 1 < multistem) { conPix = numPix - posY; posY = numPix; } else { posY += multistem; } for (int i = 1; i <= conPix; i++) { mCL.initialiseSTEMWaveFunction(((LockedArea.xStart + Pixels[(thisPosY + i - 1)].Item1 * xInterval - SimRegion.xStart) / pixelScale), ((LockedArea.yStart + Pixels[(thisPosY + i - 1)].Item2 * yInterval - SimRegion.yStart) / pixelScale), i); } // Use Background worker to progress through each step int NumberOfSlices = 0; mCL.getNumberSlices(ref NumberOfSlices, isFD); // Seperate into setup, loop over slices and final steps to allow for progress reporting. for (int i = 1; i <= NumberOfSlices; i++) { if (ct.IsCancellationRequested == true) { break; } timer.Start(); mCL.doMultisliceStep(i, NumberOfSlices, conPix); timer.Stop(); int mem = mCL.getCLMemoryUsed(); float ms = timer.ElapsedMilliseconds; progressReporter.ReportProgress((val) => { CancelButton.IsEnabled = true; // Note: code passed to "ReportProgress" can access UI elements freely. UI_UpdateSimulationProgressSTEM(ms, totalPix, pix, NumberOfSlices, i, mem); }, i); } pix += conPix; if (ct.IsCancellationRequested == true) { break; } for (int i = 1; i <= conPix; i++) { // After a complete run if TDS need to sum up the DIFF... //mCL.AddTDSDiffImage(TDSImages[i-1], CurrentResolution,i); // Sum it in C++ also for the stem pixel measurement... //mCL.AddTDS(i); mCL.getSTEMDiff(i); } progressReporter.ReportProgress((val) => { CancelButton.IsEnabled = false; //UpdateTDSImage(); }, j); for (int p = 1; p <= conPix; p++) { // loop through and get each STEM pixel for each detector at the same time foreach (DetectorItem i in LockedDetectors) { float pixelVal = mCL.getSTEMPixel(i.Inner, i.Outer, i.xCentre, i.yCentre, p); float newVal = i.ImageData[LockedArea.xPixels * Pixels[thisPosY + p - 1].Item2 + Pixels[thisPosY + p - 1].Item1] + pixelVal; i.ImageData[LockedArea.xPixels * Pixels[thisPosY + p - 1].Item2 + Pixels[thisPosY + p - 1].Item1] = newVal; //if (j == runs-1) // Only use final values to set contrast limits //{ if (newVal < i.Min) { i.Min = newVal; } if (newVal > i.Max) { i.Max = newVal; } //} } } // This will update display after each tds run... progressReporter.ReportProgress((val) => { foreach (DetectorItem i in LockedDetectors) { UpdateDetectorImage(i); } }, thisPosY); if (ct.IsCancellationRequested == true) { break; } } // Reset TDS arrays after pixel values retrieved //mCL.ClearTDS(multistem); //fCoordxs.Clear(); if (ct.IsCancellationRequested == true) { break; } } }
private void SimulationMethod(bool select_TEM, bool select_STEM, bool select_CBED, int TDSruns, ref ProgressReporter progressReporter, ref Stopwatch timer, ref CancellationToken ct) { // Add Pixelscale to image tabs and diffraction then run simulation if (select_TEM) { EWDisplay.PixelScaleX = pixelScale; DiffDisplay.PixelScaleX = pixelScale; EWDisplay.PixelScaleY = pixelScale; DiffDisplay.PixelScaleY = pixelScale; EWDisplay.xStartPosition = SimRegion.xStart; EWDisplay.yStartPosition = SimRegion.yStart; SimulateTEM(ref progressReporter, ref timer, ref ct); } else if (select_STEM) { UInt64 mem = mCL.getCLdevGlobalMemory(); UInt64 multi64 = mem / ((UInt64)CurrentResolution * (UInt64)CurrentResolution * 8 * 4); int multistem = (int)multi64; DiffDisplay.PixelScaleX = pixelScale; DiffDisplay.PixelScaleY = pixelScale; SimulateSTEM(TDSruns, ref progressReporter, ref timer, ref ct, multistem); } else if (select_CBED) { DiffDisplay.PixelScaleX = pixelScale; DiffDisplay.PixelScaleY = pixelScale; SimulateCBED(TDSruns, ref progressReporter, ref timer, ref ct); } }
// Simulation Button private void SimulationButton(object sender, RoutedEventArgs e) { select_TEM = TEMRadioButton.IsChecked == true; select_STEM = STEMRadioButton.IsChecked == true; select_CBED = CBEDRadioButton.IsChecked == true; if (!TestSimulationPrerequisites()) { return; } Application.Current.Resources["Accent"] = Application.Current.Resources["ErrorColOrig"]; CurrentResolution = Resolution; CurrentPixelScale = pixelScale; CurrentWavelength = wavelength; CurrentVoltage = ImagingParameters.kilovoltage; // DiffDisplay.tCanvas.Width = CurrentResolution; // DiffDisplay.tCanvas.Height = CurrentResolution; SimulateEWButton.IsEnabled = false; SimulateImageButton.IsEnabled = false; var TDSruns = 1; if (select_STEM) { TDSruns = Convert.ToInt32(STEM_TDSCounts.Text); } else if (select_CBED) { TDSruns = Convert.ToInt32(CBED_TDSCounts.Text); } this.cancellationTokenSource = new CancellationTokenSource(); var cancellationToken = this.cancellationTokenSource.Token; var progressReporter = new ProgressReporter(); // Pull options from dialog Single.TryParse(SliceDz.Text, out dz); Int32.TryParse(Full3DIntegrals.Text, out integrals); CancelButton.IsEnabled = false; var task = Task.Factory.StartNew(() => { Thread.CurrentThread.Priority = ThreadPriority.Normal; var timer = new Stopwatch(); // Upload Simulation Parameters to c++ class mCL.setCTEMParams(ImagingParameters.df, ImagingParameters.astigmag, ImagingParameters.astigang, ImagingParameters.kilovoltage, ImagingParameters.spherical, ImagingParameters.beta, ImagingParameters.delta, ImagingParameters.aperturemrad, ImagingParameters.astig2mag, ImagingParameters.astig2ang, ImagingParameters.b2mag, ImagingParameters.b2ang); mCL.setSTEMParams(ProbeParameters.df, ProbeParameters.astigmag, ProbeParameters.astigang, ProbeParameters.kilovoltage, ProbeParameters.spherical, ProbeParameters.beta, ProbeParameters.delta, ProbeParameters.aperturemrad); SimulationMethod(select_TEM, select_STEM, select_CBED, TDSruns, ref progressReporter, ref timer, ref cancellationToken); }, cancellationToken); // This runs on UI Thread so can access UI, probably better way of doing image though. //SimWorker.RunWorkerCompleted += delegate(object s, RunWorkerCompletedEventArgs args) progressReporter.RegisterContinuation(task, () => { CancelButton.IsEnabled = false; ProgressBar1.Value = 100; ProgressBar2.Value = 100; if (select_STEM) { if (LockedDetectors.Count == 0) { SimulateEWButton.IsEnabled = true; return; } foreach (var i in LockedDetectors) { UpdateDetectorImage(i); } // just select the first tab for convenience LockedDetectors[0].Tab.IsSelected = true; SaveImageButton.IsEnabled = true; } else if (select_CBED) { UpdateTDSImage(); SaveImageButton2.IsEnabled = true; } else { UpdateEWImage(); EWDisplay.Tab.IsSelected = true; UpdateDiffractionImage(); SaveImageButton.IsEnabled = true; SaveImageButton2.IsEnabled = true; SimulateImageButton.IsEnabled = true; } Application.Current.Resources["Accent"] = Application.Current.Resources["AccentOrig"]; SimulateEWButton.IsEnabled = true; }); }
private void ImportStructureButton(object sender, RoutedEventArgs e) { var openDialog = new Microsoft.Win32.OpenFileDialog { FileName = "file name", DefaultExt = ".xyz", Filter = "XYZ Coordinates (.xyz)|*.xyz" }; // Set defaults for file dialog. var result = openDialog.ShowDialog(); if (result == true) { var fName = openDialog.FileName; fileNameLabel.Text = System.IO.Path.GetFileName(fName); fileNameLabel.ToolTip = fName; // Now pass filename through to unmanaged where atoms can be imported inside structure class... mCL.importStructure(openDialog.FileName); mCL.uploadParameterisation(); // Update some dialogs if everything went OK. var Len = 0; float MinX = 0; float MinY = 0; float MinZ = 0; float MaxX = 0; float MaxY = 0; float MaxZ = 0; mCL.getStructureDetails(ref Len, ref MinX, ref MinY, ref MinZ, ref MaxX, ref MaxY, ref MaxZ); HaveStructure = true; WidthLabel.Content = (MaxX - MinX).ToString("f2") + " Å"; HeightLabel.Content = (MaxY - MinY).ToString("f2") + " Å"; DepthLabel.Content = (MaxZ - MinZ).ToString("f2") + " Å"; AtomNoLabel.Content = Len.ToString(); if (!userSTEMarea) { STEMRegion.xFinish = Convert.ToSingle((MaxX - MinX).ToString("f2")); STEMRegion.yFinish = Convert.ToSingle((MaxY - MinY).ToString("f2")); } if (!userSIMarea) { SimRegion.xFinish = Convert.ToSingle((MaxX - MinX).ToString("f2")); SimRegion.yFinish = Convert.ToSingle((MaxY - MinY).ToString("f2")); } UpdatePx(); // Now we want to sorting the atoms ready for the simulation process do this in a background worker... this.cancellationTokenSource = new CancellationTokenSource(); var cancellationToken = this.cancellationTokenSource.Token; var progressReporter = new ProgressReporter(); var task = Task.Factory.StartNew(() => { // This is where we start sorting the atoms in the background ready to be processed later... mCL.sortStructure(false); return(0); }, cancellationToken); // This runs on UI Thread so can access UI, probably better way of doing image though. progressReporter.RegisterContinuation(task, () => { IsSorted = true; }); } }