/// <summary> /// Clean up any resources being used. /// </summary> /// <param name="disposeEvenManagedStuff">true to dispose managed and unmanaged resources; false to dispose unmanaged resources</param> protected void Dispose(bool disposeEvenManagedStuff) { // prevent double disposing if (Interlocked.Exchange(ref m_disposed, 1) != 0) { return; } if ((Arguments != null) && Arguments.RepeatingScanTest && repeatingScanStarted && (InstrumentInstance != null)) { ScansTest.CancelRepeatingScan(InstrumentInstance); } if (disposeEvenManagedStuff) { if (m_scansOutput != null) { m_scansOutput.CloseDown(); m_scansOutput = null; } if (m_analogOutput != null) { m_analogOutput.CloseDown(); m_analogOutput = null; } if (m_valuesTest != null) { m_valuesTest.CloseDown(); m_valuesTest = null; } if (m_scansTest != null) { m_scansTest.Dispose(); m_scansTest = null; } if (m_methodsTest != null) { m_methodsTest.CloseDown(); m_methodsTest = null; } if (InstrumentInstance != null) { InstrumentInstance.Dispose(); InstrumentInstance = null; } } IInstrumentAccessContainer container = Container; Container = null; if (container != null) { IDisposable disp = container as IDisposable; if (disp != null) { disp.Dispose(); } } }
/// <summary> /// Open a connection to the API and return the first instrument. Expect exceptions on errors accessing the API. /// </summary> /// <returns>Returns an implementation of the first instrument of the API that REQUIRES a call to Dispose finally.</returns> static internal IExactiveInstrumentAccess GetFirstInstrument() { if (m_container == null) { m_container = GetContainer(); } return((IExactiveInstrumentAccess)m_container.Get(1)); }
// perform the work: internal void DoJob() { IInstrumentAccessContainer container = GetApiInstance(); using (IInstrumentAccess instrument = container.Get(1)) { // we just print the instrument name. Console.WriteLine(instrument.InstrumentName); } }
/// <summary> /// The user requests to test the presence of the API. /// </summary> /// <param name="sender">doesn't matter</param> /// <param name="e">doesn't matter</param> private void ButtonInterfaceTest_Click(object sender, EventArgs e) { try { IInstrumentAccessContainer container = GetApiInstance(); using (IInstrumentAccess instrument = container.Get(1)) { // get access to the first instrument, but release it immediately. } // Success! TextBoxStatus.Text = "The API of Exactive Series instruments is present and functional."; } catch (Exception ex) { DumpExceptionToStatusBox(ex); } }
/// <summary> /// The user wants to actively change a value. This may or may not lead /// to an exception if privileges are missing or if the proper role is not assumed. /// </summary> /// <param name="sender">doesn't matter</param> /// <param name="e">doesn't matter</param> private void ButtonSprayVoltage_Click(object sender, EventArgs e) { try { IInstrumentAccessContainer container = GetApiInstance(); using (IInstrumentAccess instrument = container.Get(1)) { TextBoxStatus.Text = "Waiting for spray voltage to become available..."; IValue value = instrument.Control.InstrumentValues.Get("SourceSprayVoltage"); DateTime timeout = DateTime.Now + TimeSpan.FromSeconds(5); while (value.Content.Content == null) { // Thread.Join continues to process the current message loop Thread.CurrentThread.Join(10); if (DateTime.Now > timeout) { break; } } if (value.Content.Content == null) { TextBoxStatus.Text = "Either no link to the instrument or the spray voltage is not a tuneable value of the source."; } else { TextBoxStatus.Text = "About to set the spray voltage..."; Application.DoEvents(); string previous = value.Content.Content; bool ok = value.Set("100"); TextBoxStatus.Text = "Changing spray voltage from " + previous + " to 100: " + ((ok) ? "OK" : "impossible to set"); } } } catch (Exception ex) { DumpExceptionToStatusBox(ex); } }
public void RunMachine(Planner runManager, string filename, bool auto) { runProgram = runManager; // Instrument access setup stuff. if (!auto) { Console.WriteLine("Ready. (Press any key.)"); Console.ReadKey(); } string device_registration = ((IntPtr.Size > 4) ? @"SOFTWARE\Wow6432Node\Finnigan\Xcalibur\Devices\" : @"SOFTWARE\Finnigan\Xcalibur\Devices\") + "Thermo Exactive"; string asmName = "None"; string typeName = "None"; RegistryKey key = Registry.LocalMachine.OpenSubKey(device_registration); Debug.Assert(key != null); asmName = (string)key.GetValue("ApiFileName_Clr2_32_V1", null); typeName = (string)key.GetValue("ApiClassName_Clr2_32_V1", null); Console.WriteLine("ASM: " + asmName + "\nType: " + typeName); Directory.SetCurrentDirectory(Path.GetDirectoryName(asmName)); Assembly asm = Assembly.LoadFrom(asmName); object api_obj = asm.CreateInstance(typeName); container = api_obj as IInstrumentAccessContainer; Debug.Assert(container != null); instrument = container.Get(1); Debug.Assert(instrument != null); iexactive = instrument as IExactiveInstrumentAccess; Debug.Assert(iexactive != null); control = iexactive.Control; acquisition = control.Acquisition as IExactiveAcquisition; scanner = control.GetScans(false); runProgram.Initialize(scanner); // Attaching a simple function to on-new-scan event; equivalent of wx.Bind. IMsScanContainer scancontainer = iexactive.GetMsScanContainer(0); scancontainer.AcquisitionStreamOpening += new EventHandler <MsAcquisitionOpeningEventArgs>(goahead_Response); scancontainer.AcquisitionStreamClosing += new EventHandler(stop_Response); scancontainer.MsScanArrived += new EventHandler <MsScanEventArgs>(scanArrived_Response); scanner.CanAcceptNextCustomScan += new EventHandler(readyForScan_Response); acquisition.StateChanged += new EventHandler <StateChangedEventArgs>(note_state_change); machine_voltage = control.InstrumentValues.Get("SourceSprayVoltage"); machine_voltage.ContentChanged += new EventHandler <Thermo.Interfaces.InstrumentAccess_V1.Control.ContentChangedEventArgs>(voltageChangeResponse); Thread.Sleep(100); // Gives machine_voltage a chance to get its act together. current_voltage = Double.Parse(machine_voltage.Content.Content); change_voltage(0); // Submitting method and running. Console.WriteLine("Starting State=" + acquisition.State.SystemState); // Attempts to control machine state; should be "On" after this code block. ChangeResult set_to_standby_result = acquisition.SetMode(acquisition.CreateForcedStandbyMode()); acquisition.WaitFor(TimeSpan.FromSeconds(3), SystemMode.Standby); ChangeResult set_to_on_result = acquisition.SetMode(acquisition.CreateOnMode()); acquisition.WaitFor(TimeSpan.FromSeconds(3), SystemMode.On); authorized_for_run = false; accepting_scans = false; IAcquisitionWorkflow methodWorkflow = null; methodWorkflow = acquisition.CreatePermanentAcquisition(); methodWorkflow.RawFileName = filename; // Numbers are appended to file name on overwrite. if (USE_CONTACT_CLOSURE) { ITrigger ccTrigger = acquisition.CreateTrigger("WaitForContactClosure"); methodWorkflow.Trigger = ccTrigger; } else { authorized_for_run = true; Console.WriteLine("NON-CONTACT CLOSURE START."); } ChangeResult start_acq_result = acquisition.StartAcquisition(methodWorkflow); //methodWorkflow.SingleProcessingDelay = 600.0D; // Doesn't work! run_is_active = true; intendedRunTime = TimeSpan.FromSeconds(intended_run_seconds); runTimeKeeper = new Stopwatch(); Console.WriteLine("Waiting for goahead..."); while (!authorized_for_run) { Thread.Sleep(100); } Console.WriteLine("Got goahead."); Thread.Sleep(column_wait_time_seconds * 1000); Console.WriteLine("Column wait over, setting charge up."); change_voltage(working_voltage); bool got_to_workable_state = acquisition.WaitFor(TimeSpan.FromSeconds(5), SystemMode.On, SystemMode.DirectControl); if (!got_to_workable_state) { Console.WriteLine("Invalid state " + acquisition.State.SystemMode + " before scan submission. Done."); if (!auto) { Console.ReadKey(); } Environment.Exit(0); } Console.WriteLine("Starting."); runTimeKeeper.Start(); // This had been before contact closure confirmation! accepting_scans = true; Thread scan_handler = new Thread(scan_assignment_handler); scan_handler.Start(); //Debug.Assert(!acquisition.WaitFor(intendedRunTime, SystemMode.Standby)); // Wait while things run; state shouldn't change. // COULD PROBABLY do something with AcquisitionStreamClosing instead. Console.WriteLine("In run loop."); while (runTimeKeeper.Elapsed < intendedRunTime) { Thread.Sleep(100); } Console.WriteLine("Closing up."); authorized_for_run = false; accepting_scans = false; //run_is_active = false; //scan_handler.Abort(); scan_handler.Join(); Console.WriteLine("Joined."); change_voltage(0); ChangeResult cancel_result = acquisition.CancelAcquisition(); Console.WriteLine("Cancellation result: " + cancel_result.ToString()); Console.WriteLine("Setting mode to standby."); ChangeResult setmode2_result = acquisition.SetMode(acquisition.CreateForcedStandbyMode()); Console.WriteLine("Set mode result: " + setmode2_result.ToString()); //if (run_is_active) //{ // Console.WriteLine("Acquisition closed immediately/already."); //} else //{ // Console.WriteLine("Waiting for acquisition close event."); // Stopwatch CloseTimer = new Stopwatch(); // CloseTimer.Start(); // while (run_is_active) // { // Thread.Sleep(100); // } // Console.WriteLine("Close event received after " + CloseTimer.Elapsed.ToString() + " seconds."); //} runManager.Cleanup(); Console.WriteLine("Safety wait."); Thread.Sleep(15 * 1000); // Should match SingleProcessingDelay used by Planner. Console.WriteLine("Done."); if (!auto) { Console.ReadKey(); } Environment.Exit(0); }