4 Replies Latest reply on Sep 22, 2017 3:43 AM by jigr1969

    Mass Hunter Crashing

    jigr1969

      Hi all.

       

      I have some code, penned in Iron Python, which I'm trying to get to run from a menu item selection. When I select and execute similar code using the Tools -> Actions -> Custom Action, it works as intended. If I put it within code to run when a menu item is clicked, it simply crashes the Mass Hunter Application! The log file complains about a global name not being defined, which I can imagine, but it isn't defined in either.

       

      The code here is the one which runs when the button is clicked and is loaded with Mass hunter by using the "-app=" command line parameter.

       

      # The two main imports for IronPython (as I've found out).

      import clr

      import sys

       

      # This appends the path, adding the Iron Python libraries location.

      sys.path.append(r'C:\Program Files (x86)\IronPython 2.7')

      sys.path.append(r'C:\Program Files (x86)\IronPython 2.7\Lib')

      sys.path.append(r'C:\Program Files (x86)\IronPython 2.7\DLLs')

      sys.path.append(r'C:\Program Files (x86)\IronPython 2.7\lib\site-packages')

      sys.path.append(r'C:\Program Files (x86)\IronPython 2.7\Platforms\Net40')

       

      # Add in manually items required for the script.

      clr.AddReference("Microsoft.Office.Interop.Excel")

      clr.AddReference("System.Windows.Forms")

      clr.AddReference('IronPython.Wpf')

       

      # Import modules that were added manually from above.

      import csv

      import os;

      import os.path

      import wpf

      import Microsoft.Office.Interop.Excel as Excel

       

      # Import specific classes from modules as opposed to full modules.

      from System.Windows import Application, Window

      from Microsoft.Win32 import OpenFileDialog

      from System import Array

      from System.Windows.Forms import (

          FolderBrowserDialog, MessageBox, MessageBoxButtons

      )

       

      clr.AddReference("QuantUIScriptIF")

      clr.AddReference("System.Windows.Forms")

       

      import System

      import Agilent

       

      from Agilent.MassSpectrometry.DataAnalysis.Quantitative.UIScriptIF import *

       

      def SetState(ToolState, UIState):

       

             # always enable the tool

             ToolState.Enabled = True

       

      def Execute(ToolState, UIState):

       

              # Declare variables.

             batchId = 0

             SetTrue = bool(1)

       

             # Placed in order to allow the software to be seen as running.

             MessageBox.Show("Hi honey I'm home!", "Warning")

       

             # Access sample table with object model.

             batchTable = BatchDataSet.BatchTable

       

             # Retrieve samples in the batch

             sampleRows = batchTable.Select("BatchID=%s" %(str(batchId)))

       

             # Walk through all samples.

             for s in range(0, len(sampleRows)):

                    sampleRow = sampleRows[s]

                    sId = sampleRow["SampleID"]

                    _commands.QuantSetSampleAttribute(batchId, sId, "SampleApproved", SetTrue)

       

       

      The code below is called and executed by the Action script menu, which works as intended.

       

      # The two main imports for IronPython (as I've found out).

      import clr

      import sys

       

      # This appends the path, adding the Iron Python libraries location.

      sys.path.append(r'C:\Program Files (x86)\IronPython 2.7')

      sys.path.append(r'C:\Program Files (x86)\IronPython 2.7\Lib')

      sys.path.append(r'C:\Program Files (x86)\IronPython 2.7\DLLs')

      sys.path.append(r'C:\Program Files (x86)\IronPython 2.7\lib\site-packages')

      sys.path.append(r'C:\Program Files (x86)\IronPython 2.7\Platforms\Net40')

       

      # Add in manually items required for the script.

      clr.AddReference("Microsoft.Office.Interop.Excel")

      clr.AddReference("System.Windows.Forms")

      clr.AddReference('IronPython.Wpf')

       

      # Import modules that were added manually from above.

      import csv

      import os;

      import os.path

      import wpf

      import Microsoft.Office.Interop.Excel as Excel

       

      # Import specific classes from modules as opposed to full modules.

      from System.Windows import Application, Window

      from Microsoft.Win32 import OpenFileDialog

      from System import Array

      from System.Windows.Forms import (

          FolderBrowserDialog, MessageBox, MessageBoxButtons

      )

       

      # Declare variables.

      batchId = 0

      SetTrue = bool(1)

       

      MessageBox.Show("Hi honey I'm home!", "Warning")

       

      # Access sample table with object model.

      batchTable = BatchDataSet.BatchTable

       

      # Retrieve samples in the batch

      sampleRows = batchTable.Select("BatchID=%s" %(str(batchId)))

       

      # Walk through all samples.

      for s in range(0, len(sampleRows)):

              sampleRow = sampleRows[s]

              sId = sampleRow["SampleID"]

              _commands.QuantSetSampleAttribute(batchId, sId, "SampleApproved", SetTrue)

       

       

      Now the log file created when it crashes has the following entries of interest:

       

      09/21/2017 03:24:38 PM [ERROR] ScriptToolHandler: Agilent.MassSpectrometry.DataAnalysis.Quantitative.ApplicationCommandException: Script runtime error: global name 'BatchDataSet' is not defined ---> IronPython.Runtime.UnboundNameException: global name 'BatchDataSet' is not defined

         at IronPython.Compiler.PythonGlobal.GetCachedValue(Boolean lightThrow)

         at Help_About$3.Execute$6(PythonFunction $function, Object ToolState, Object UIState) in C:\Program Files\Agilent\MassHunter\Workstation\Quant\bin\applications\MyApp\tools\Help_About.py:line 64

         at System.Dynamic.UpdateDelegates.UpdateAndExecute4[T0,T1,T2,T3,TRet](CallSite site, T0 arg0, T1 arg1, T2 arg2, T3 arg3)

         at Microsoft.Scripting.Interpreter.DynamicInstruction`5.Run(InterpretedFrame frame)

         at Microsoft.Scripting.Interpreter.Interpreter.Run(InterpretedFrame frame)

         at Microsoft.Scripting.Interpreter.LightLambda.Run2[T0,T1,TRet](T0 arg0, T1 arg1)

         at IronPython.Compiler.PythonScriptCode.RunWorker(CodeContext ctx)

         at Microsoft.Scripting.Hosting.ScriptSource.Execute(ScriptScope scope)

         at Agilent.MassSpectrometry.DataAnalysis.Quantitative.UIScriptIFImpls.ScriptEngine.Execute(TextReader reader, Encoding encoding, IScriptScope scope)

         --- End of inner exception stack trace ---

         at Agilent.MassSpectrometry.DataAnalysis.Quantitative.UIScriptIFImpls.ScriptEngine.Execute(TextReader reader, Encoding encoding, IScriptScope scope)

         at Agilent.MassSpectrometry.DataAnalysis.Quantitative.UIUtils.ScriptToolHandler.Execute(IToolState toolState, Object objUiState)

      09/21/2017 03:24:38 PM [ERROR] ToolbarsManagerBase: Agilent.MassSpectrometry.DataAnalysis.Quantitative.ApplicationCommandException: Script runtime error: global name 'BatchDataSet' is not defined ---> IronPython.Runtime.UnboundNameException: global name 'BatchDataSet' is not defined

         at IronPython.Compiler.PythonGlobal.GetCachedValue(Boolean lightThrow)

         at Help_About$3.Execute$6(PythonFunction $function, Object ToolState, Object UIState) in C:\Program Files\Agilent\MassHunter\Workstation\Quant\bin\applications\MyApp\tools\Help_About.py:line 64

         at System.Dynamic.UpdateDelegates.UpdateAndExecute4[T0,T1,T2,T3,TRet](CallSite site, T0 arg0, T1 arg1, T2 arg2, T3 arg3)

         at Microsoft.Scripting.Interpreter.DynamicInstruction`5.Run(InterpretedFrame frame)

         at Microsoft.Scripting.Interpreter.Interpreter.Run(InterpretedFrame frame)

         at Microsoft.Scripting.Interpreter.LightLambda.Run2[T0,T1,TRet](T0 arg0, T1 arg1)

         at IronPython.Compiler.PythonScriptCode.RunWorker(CodeContext ctx)

         at Microsoft.Scripting.Hosting.ScriptSource.Execute(ScriptScope scope)

         at Agilent.MassSpectrometry.DataAnalysis.Quantitative.UIScriptIFImpls.ScriptEngine.Execute(TextReader reader, Encoding encoding, IScriptScope scope)

         --- End of inner exception stack trace ---

         at Agilent.MassSpectrometry.DataAnalysis.Quantitative.UIScriptIFImpls.ScriptEngine.Execute(TextReader reader, Encoding encoding, IScriptScope scope)

         at Agilent.MassSpectrometry.DataAnalysis.Quantitative.UIUtils.ScriptToolHandler.Execute(IToolState toolState, Object objUiState)

         at Agilent.MassSpectrometry.DataAnalysis.Quantitative.Toolbar.ToolbarsManagerBase.Execute(IToolState tool)

      09/21/2017 03:24:38 PM [FINISH] ToolbarsManagerBase: Execute

       

      This to me feels like that I'm not referencing a global variable in the correct manner, not for when it is being called from within a function.

       

      Any help is greatly appreciated on this manner.

       

      It is taking me a while to get to this stage with Mass Hunter and Iron Python and I can see the combination has plenty of potential.

        • Re: Mass Hunter Crashing
          jigr1969

          Changing the code in the code which is called from the menu item from

           

          def Execute(ToolState, UIState):

           

                  # Declare variables.

                 batchId = 0

                 SetTrue = bool(1)

           

                 # Placed in order to allow the software to be seen as running.

                 MessageBox.Show("Hi honey I'm home!", "Warning")

           

                 # Access sample table with object model.

                 batchTable = BatchDataSet.BatchTable

           

                 # Retrieve samples in the batch

                 sampleRows = batchTable.Select("BatchID=%s" %(str(batchId)))

           

                 # Walk through all samples.

                 for s in range(0, len(sampleRows)):

                        sampleRow = sampleRows[s]

                        sId = sampleRow["SampleID"]

                        _commands.QuantSetSampleAttribute(batchId, sId, "SampleApproved", SetTrue)

           

          to

           

          def Execute(ToolState, UIState):

           

                # Declare variables.

                batchId = 0

                SetTrue = bool(1)

           

                MessageBox.Show("Hi honey I'm home!", "Warning")

           

                _commands.QuantAnalyze(0)

           

          once again results in Mass Hunter crashing.

           

          Now the interesting thing is that with the first code in place and no batch file loaded for analyse, it works without doing anything. Load a batch file in and then it starts to crash which bemuses me since the only thing that should not be running in the first example is the loop going through the sample rows, since there aren't any. This does make me wonder if the "batchTable" global variable is at fault or not.

          • Re: Mass Hunter Crashing
            jigr1969

            In further to the above, changing the code to

             

                    # Walk through all samples.

                    for s in range(0, len(sampleRows)):

                            sampleRow = sampleRows[s]

                            sId = sampleRow["SampleID"]

                            #_commands.QuantSetSampleAttribute(batchId, sId, "SampleApproved", SetTrue)

             

            such that the "_commands" is commented out, results in Mass Hunter not crashing on me. So what is it about that command or parameters which is causing such an issue that Mass Hunter cannot handle (in error exception routine).

            • Re: Mass Hunter Crashing
              jigr1969

              Following on from my previous post, I now see that all of the parameters have a value, as proved by the code

               

                      print 'Length of sampleRows is '+str(len(sampleRows))

               

                      # Walk through all samples.

                      for s in range(0, len(sampleRows)):

                              sampleRow = sampleRows[s]

                              sId = sampleRow["SampleID"]

               

                              print 'sID equals '+str(sId)

               

                              #_commands.QuantSetSampleAttribute(batchId, sId, "SampleApproved", SetTrue)

               

              Which gives the output of

               

              $ "C:\Program Files\Agilent\MassHunter\Workstation\Quant\bin\QuantAnalysis.exe" -app=MyApp

              Batch ID is 0

              Length of sampleRows is 0

              Batch ID is 0

              Length of sampleRows is 14

              sID equals 0

              sID equals 1

              sID equals 2

              sID equals 3

              sID equals 4

              sID equals 5

              sID equals 6

              sID equals 7

              sID equals 8

              sID equals 9

              sID equals 10

              sID equals 11

              sID equals 12

              sID equals 13

               

              So it has to be the function call which is an issue.

               

              (The batch ID and length of sample rows are listed twice as I do click on the menu item twice, once without a batch loaded, one with.)

              • Re: Mass Hunter Crashing
                jigr1969

                Okay having figured out that it was the actual "_commands" that was causing the issue as opposed to anything else that the log file suggested it was in the opening post, I looked int that.

                 

                To fix the issue, I had to include the line "import _commands" along with the other imports.

                 

                Why this is required when running via a menu item and not when running via the "Custom Action" can only be put down to the run time environment. When calling via a menu item, you need to set everything up manually, but from the "Custom Action" it is setup automatically. Yes I am guessing at this, I await to see if anyone from Agilent can confirm this or not.