/// <summary> /// SaveAsR3D saves the current file as an R3D /// file. /// </summary> /// <param name="fileName">The R3D file to which to save the data</param> private void SaveAsR3D(String fileName) { //Create a new SHArK File ISHArKFile newFile = SHArKFileFactory.Create(fileName, true); //Add all of the header data to the File newFile.Comment = this._file.Comment; //Add all of the numerical data to the File foreach (Point p in this._file.Points) { newFile.AddDataPoint(p); } }
/// <summary> /// Acquire3DData is called in a separate thread to /// acquire the data set up in the NewSpectrumInfo /// object passed to the Tab. /// </summary> private void Acquire3DData() { //Set the Mouse cursor this._view.Dispatcher.Invoke(new SetMouseCursorDelegate(this.SetMouseCursor), Cursors.Wait); //Set the basic Chart Properties this._view.Dispatcher.Invoke(new SetDocumentNameDelegate(this.SetDocumentName), Path.GetFileName(this._newSpecInfo.FileName)); this._view.Dispatcher.Invoke(new SetAxisRangesDelegate(this.SetAxisRanges), this._newSpecInfo.Columns - 1, this._newSpecInfo.Rows - 1); //Set the run state on the Chart this._view.Dispatcher.Invoke(new SetRunStateDelegate(this.SetRunState), true); //Get the Hardware objects -- just return //if any of them is null IMirror mirror = null; IPotentiostat potstat = null; ILaser laser = null; this.GetHardwareObjects(ref mirror, ref potstat, ref laser); if (mirror == null || potstat == null || laser == null) { return; } //Try to run the entire Acquisition try { //Initialize the new SHArKFile ISHArKFile file = SHArKFileFactory.Create(this._newSpecInfo.FileName, true); //Set the potential on the electrode potstat.SetPotential(this._newSpecInfo.BiasPotential); //Reset the Laser to the Initial Position this._view.Dispatcher.Invoke(new SetWindowStatusDelegate(this.SetWindowStatus), Strings.ResetInitialPosition); this.SetInitialLaserPosition(mirror, this._newSpecInfo.Columns, 0); //Finally, reset the mouse cursor so that the user //can see that initial processing is over this._view.Dispatcher.Invoke(new SetMouseCursorDelegate(this.SetMouseCursor), Cursors.Arrow); //Check the Poteniostat to see if the current is too //high to start a scan -- open the box if necessary if (potstat.IsCurrentSettled == false) { this._view.Dispatcher.Invoke(new ShowDarkCurrentDialogDelegate(this.ShowDarkCurrentDialog), potstat); } //Do the acquisition while the user does not //want to Pause or Stop Int32 xIndex = 0; Int32 yIndex = this._newSpecInfo.Rows - 1; Int32 xStep = this._newSpecInfo.StepSize; while (this.IsRunning == true) { //Get the time remaining as a String TimeSpan tsRemaining = this._newSpecInfo.CalculateTimeRemaining(xIndex, yIndex); String timeRemaining = String.Format("{0:D2}:{1:D2}:{2:D2}", tsRemaining.Hours, tsRemaining.Minutes, tsRemaining.Seconds); //Set the status on the Window to show that the //scan is running this._view.Dispatcher.Invoke(new SetWindowStatusDelegate(SetWindowStatus), String.Format("{0} {1} Remaining", Strings.ScanRunning, timeRemaining)); //Get the Dark Current value from the Potentiostat Double darkCurrent = potstat.GetCurrent(this._newSpecInfo.NumberCurrentSamples); //Turn on the Laser and wait the specified amount of time laser.SetLaserState(true); Thread.Sleep(this._newSpecInfo.MillisecondsLaserOnDelay); //Acquire the data for the current point Double lightCurrent = potstat.GetCurrent(this._newSpecInfo.NumberCurrentSamples); //Add the Point to the file Point p = new Point(xIndex, yIndex, lightCurrent - darkCurrent); file.AddDataPoint(p); //Turn off the laser and wait the specified amount of time laser.SetLaserState(false); Thread.Sleep(this._newSpecInfo.MillisecondsLaserOffDelay); //Set the Point in the ObservableCollection so //that it updates the Chart this._view.Dispatcher.Invoke(new AddPointsToChartDelegate(this.AddPointsToChart), new Point[] { p }, this._newSpecInfo.MaxCurrentValue); //Determine the direction of the X-Axis movement -- //if this is an odd row (relative to starting at //this._newSpecInfo.Rows - 1), move backward xStep = this._newSpecInfo.StepSize; if ((this._newSpecInfo.Rows % 2 == 0 && yIndex % 2 == 0) || (this._newSpecInfo.Rows % 2 == 1 && yIndex % 2 == 1)) { xStep *= -1; } //Determine if the Y-Axis mirror needs to move. //If the direction is positive, move when the //X-Axis gets to Columns. Otherwise, move when //the X-Axis gets to 0. if ((xStep > 0 && xIndex == this._newSpecInfo.Columns - 1) || (xStep < 0 && xIndex == 0)) { //Move the Y-Axis Mirror mirror.Move(MirrorAxis.Y, this._newSpecInfo.StepSize); //Update the yIndex yIndex--; } //Move to the next Column if necessary if ((xStep > 0 && xIndex < this._newSpecInfo.Columns - 1) || (xStep < 0 && xIndex > 0)) { //Move to the next Column mirror.Move(MirrorAxis.X, xStep); //Update the xIndex based on the direction //of the step if (xStep > 0) { xIndex++; } else { xIndex--; } } //Check to see if the scan is finished if (yIndex == -1 && ((xStep > 0 && xIndex == this._newSpecInfo.Columns - 1) || (xStep < 0 && xIndex == 0))) { this.IsRunning = false; } //If the user has Paused the acquisition, //loop and Sleep until resumed while (this.IsPaused == true && this.IsRunning == true) { //Stop the Laser from modulating laser.SetLaserState(false); //Set the status on the Window this._view.Dispatcher.Invoke(new SetWindowStatusDelegate(this.SetWindowStatus), String.Format("{0} {1} Remaining", Strings.ScanPaused, timeRemaining)); //Sleep for a half-second Thread.Sleep(500); } } //Stop the Laser from modulating laser.SetLaserState(false); //Move the Mirror back to the Initial Position this._view.Dispatcher.Invoke(new SetWindowStatusDelegate(this.SetWindowStatus), Strings.ResetInitialPosition); this.SetInitialLaserPosition(mirror, xIndex, yIndex); } catch (System.Exception e) { //Show an error message and return this._view.Dispatcher.Invoke(new ShowErrorDelegate(this.ShowError), e.Message); return; } finally { //Clean up the Hardware objects if (mirror != null) { mirror.Dispose(); } if (potstat != null) { potstat.SetPotential(0.0); potstat.Dispose(); } if (laser != null) { laser.SetLaserState(false); laser.Dispose(); } //Publish the event to notify that the Spectrum //has finished this._view.Dispatcher.Invoke(new NotifySpectrumEndedDelegate(this.NotifySpectrumEnded)); //Reset the Window Status this._view.Dispatcher.Invoke(new SetWindowStatusDelegate(this.SetWindowStatus), String.Empty); } }