
Using Scripts with NairnFEAMPM
NairnFEAMPM is a scriptable application by two different methods. First, NairnFEAMPM can be controlled by external scripts written Apple Script, Python, or Ruby that can run multiple FEA or MPM calculations, do data analysis, or create multiple input files (the recommended option is to use Python scripts). The help topics for this style of scripting are as follows:
Second, NairnFEAMPM can be scripting using internal scripting control options. Internal methods are faster and keeps everything self-contained within NairnFEAMPM. If Apple decides (for bogus security reasons) to eliminate the options for external scripts, the internal scripting control option will always be available.
The Scripts Menu
The scripts menu (scroll icon menu) lists all AppleScript (extensions scpt
or applescript
), Python (extension py
), or Ruby (extension rb
) scripts stored in the folder containing the front document or in the folder ~/Library/Scripts/NairnFEAMPM Scripts
. Scripts that apply to a single command or results file should be stored in the same folder as that file. Generic scripts can be stored in the NairnFEAMPM Scripts
folder. If desired, you can create subfolders in either scripts location and they will result in hierarchical submenus in the scripts menu. If any scripts are found in the front document's folder, they will appear at the start of the menu in a section labeled with the folder name. Generic scripts will appear next. They will be labeled "Generic Scripts" but only have that label when folder scripts are listed as well.
To run a script, select the script from the menu. Any AppleScript output (using the message command) or returned result (at end of the script), or error message, will appear in NairnFEAMPM's message window. Similarly, Python or Ruby script output (with their standard printing commands) or error messages will appear in that message window.
Once an AppleScript starts, the script cannot be stopped from NairnFEAMPM, unless you force quit. If you need to be able to stop scripts, you can run them from Apple's Script Editor rather than from NairnFEAMPM. Once a Python or Ruby script starts, the menu command "Abort Script" will be activated (keyboard equivalent is ⌘-. (period)) and can abort the script.
Two menu commands at the bottom of the scripts menu do the following:
- Reveal Scripts in Finder - opens the
NairnFEAMPM Scripts
folder in the Finder - Refresh Scripts - resets the scripts menu to display scripts with the current front document and scripts in the
NairnFEAMPM Scripts
folder. Use this command if you change those scripts while NairnFEAMPM is running (note: the scripts menu will also refresh whenever the front document changes, if needed).
Getting Started with Scripts
This help outlines the techniques for scripting of NairnFEAMPM. Like other scriptable Mac applications, you can read all the scripting options by opening the NairnFEAMPM scripting "dictionary" using Apple's Script Editor. Scripting dictionaries define all commands and properties accessible to scripts. Since dictionaries on commands are very brief, more details on each command are listed below.
To get started, the following AppleScript is a template for automated control of NairnFEAMPM. Click each section for more details on that section. See a second template below for a similar template script in Python (which doubles as a template for Ruby scripts).
-- open a file tell application "NairnFEAMPM" open inpfile set cmdName to name of front document tell document cmdName -- set variables SetVariable named "length" value 10 -- loop over several calculations repeat with i from 1 to 10 SetVariable named "width" value i SetVariable named "archiveRoot" value "Results-" & i -- run analysis until done RunAnalysis repeat while processing is true end repeat -- save the results set fileName to (saveFolder & "/" & baseName & "-" & i & ".fea") tell application "NairnFEAMPM" save front results document in fileName end tell end repeat end tell end tell
The following Python script is a template for automated control of NairnFEAMPM. A Ruby script would be the same (except for minor differences between Ruby and Python syntax). Note that the NairnFEAMPM scripting dictionary is written for scripts written in AppleScript. The syntax for calling commands in Python or Ruby are listed below. To read properties listed in the dictionary while using Python are Ruby, the rules are to remove all spaces (if it has more than one word), capitalize the first letter of any words after a space, and then use parentheses. For example, to read "run status
" in Python or Ruby, use runStatus()
. To set a property (and only a few can be set), precede the property name with set
, capitalize the name, and follow it with underscore and the setting in parentheses. For example, to set the text
, use setText_("New Text")
.
#!/usr/bin/python # Prepare to use Apple's Scripting Bridge for Python from Foundation import * from ScriptingBridge import * import time # fetch application object and open a file nfm = SBApplication.applicationWithBundleIdentifier_("com.geditcom.NairnFEAMPM") nfm.open_(inpfile) # get front document # need get() because front document will change in the loop ndoc=nfm.documents()[0].get() # set variables ndoc.SetVariableNamed_value_("length",100) # loop over several calculations for i in range(10): ndoc.SetVariableNamed_value_("width",i+1) ndoc.SetVariableNamed_value_("archiveRoot","Results-"+str(i)) # run analysis until done ndoc.RunAnalysis() while ndoc.processing()==True: time.sleep(1.) # save the results in front document fileName=saveFolder+"/"+baseName+"-"+str(i)+".fea" nres=nfm.documents()[0].get() nres.saveAs_in_(None,saveFile)
Prepare to use Apple's Scripting Bridge
Scripts written in Python or Ruby use Apple's Scripting Bridge, which became available in MacOS 10.5. The first step is to import the Apple "Foundation" and "Scripting Bridge" libraries. The Python commands are in the above template; the corresponding commands in Ruby are
require "osx/cocoa" include OSX OSX.require_framework 'ScriptingBridge'
Next, all Python and Ruby scripts will fetch the application object for NairnFEAMPM, which is set equal to the variable nfm
in the template script.
Python scripts can use custom modules. If you use a from
or import
command, NairnFEAMPM will first look for the module in the folder ~/Library/Scripts/NairnFEAMPM Scripts/modules
. After that folder, it will search all standard locations for Python modules. You should therefore store all NairnFEAMPM-specific modules in that folder.
Open a File
This template assumes inpfile
is full path name to a valid FEA or MPM commands file, which is either coded into the script or retrieved using scripting tools (such as the user openFile command).
Alternatively, a script might be written to work on the current front document. For such scripts, there is no need to open a different file. You can check the type
property of the front document to verify it is a "Commands" or "Results" document as needed for the script.
Set Variables
SetVariable commands can set any variables. The variables can be used in the commands file. To help developing command files for use with or without scripts, a variable _ScriptMode_
will always be defined when a script is running. For example:
ifNDef _ScriptMode_ #length=20 #width=5 endif
can be used in commands. If the commands file is called from a script, the conditional will be skipped and the variables #length
and #width
will be assumed to have been defined by the script (using the SetVariable
command). When the commands file is executed normally, the conditional will set the variables.
Run Several Calculations
The point of script control is to run multiple calculations. Most script will therefore have a repeat loop. The loop will set one or more variables to some values, run an analysis, and finally read and store results are save some result to disk.
Run Analysis
The RunAnalysis
command starts the analysis. The script then needs to wait until the analysis is done, which can be done by a repeat loop that checks the processing
property. The property processing
will be true
until the calculations are done. When it becomes false, the loop exits and the script continues.
AppleScripts sometimes have problems waiting in such loops, which may be related to script time out issues. These analysis loops seem to work better in Python and is one reason Python is the recommended scripting tool.
Save Results
The results are usually saved to a file. If desired, the text in the results can be interrogated to read the results and store in text for a report (such as a spreadsheet of results) or write results to the message window.
Other Scripting Options
The above templates can easily be expanded with any features of AppleScript, Python or Ruby, or by using built-in commands in NairnFEAMPM. For example, you can save key results to a text file (using a scriptable text application such as TextEdit or by saving text in the message window), plot the results (using a scriptable plotting program), or anything else possible in scripts.
The options for scripting NairnFEAMPM will expand as needed. Below are the current commands that can be sent to NairnFEAMPM or to various types of NairnFEAMPM documents. You can also open the NairnFEAMPM dictionary in the Script Editor for an outline of these commands (or others that might have been added, but not yet documented). The following commands (in alphabetical order) are supported. Optional arguments are in square brackets; other arguments are required. Each command is also followed by the format needed to call them in Python or Ruby scripts (which require all arguments).
closeDoc
- Closes the document and all its windows. The Apple Script close command is supposed to handle this tasks, but does not work well in Python on Ruby. This command provides a second option. If the document has been changed, any changes are lost.
Supported By: command documents, results documents, plot documents
Python or Ruby use:closeDoc()
console message log text msgText
- This command writes
msgText
to the console log, which can be read using the MacOS Console app. The argument is usually a string, but it will work with some other other objects as well (e.g., list, dictionary, number, etc.). This command is useful for debugging or a place to write messages during long calculations.
Supported By: application (AppleScript only) and documents (all scripts)
Python or Ruby use:consoleMessageLogText_(msgText)
CrackClosure tip node tipNum [to node adjNode] [normal traction normT] [shear traction shearT]
- Calculate mode I and mode II energy release rates at a crack tip. It will return a record with entries for "GI", "GII", and "Gtot" for the energy release rates. The returned record will have other calculation details as well (similar to what appears in the crack closure window). If there is a error, the returned record will have single entry "ERROR" that describes the error. The tractions allow specification of constant crack-surface tractions.
The crack tip is specified by thetip node
at the crack tip. You can optionally specify the adjacent node back from the crack tip in the intact direction (theto node
argument). When adjacent node is not specified, the calculation will search for it instead (the default and recommended method). Set the adjacent node to 0 in Python or Ruby to not specify it.
Supported By: results documents
Python or Ruby use:CrackClosureTipNode_normalTraction_shearTraction_toNode_(100,0,0,0)
ExportXML to file filename
- Export the interpreted commands in a commands document to the file in
filename
. The file name can be a POSIX path (i.e., folders separated by slashes ('/
')) or a colon-delimited path (i.e., Classic Mac path), but if a POSIX path is used, the name cannot contain any colons (':
'). This command in conjunction with theInterpret
command can save a series of input files for submitting batch jobs on a cluster.
Supported By: command documents
Python or Ruby use:ExportXMLToFile_("path to file")
find global quantity name
- Find array of an archived global quantity with the given
name
, which comes from the list of names available for global archiving.
Supported By: results documents
Python or Ruby use:findGlobalQuantity_(name)
FindNode near {x,y}
- Find node number closest to a point specified in the list argument. It will return the node number.
Supported By: results documents
Python or Ruby use:FindNodeNear_([x,y])
FindSection named sectionTitle
- Find all text of a section from a results file with the provided
sectionTitle
. It will return it as a string.
Supported By: results documents
Python or Ruby use:FindSectionNamed_(sectionTitle)
GetVariable named varName
- Get value of a variable given by string in
varName
(without the leading '#') as defined in the previous commands interpretation (it will be empty string if the variable is not defined).
Supported By: command or results documents
Python or Ruby use:GetVariableNamed_(name)
Interpret
- Interpret the commands in a commands document, but do not do the calculations. You can monitor the
processing
property of the front document to find out when the interpretation is done.
Supported By: command documents
Python or Ruby use:Interpret()
Message [set text msgText] [append addText] [save in filename]
- This commands works with the message panel. The
set text
argument will clear the panel and set it to the providedmsgText
. Theappend
argument will appendaddText
to the message panel. Thesave in
argument will save the current message panel text in the file with path infilename
(a colon-delimited path from Classic Mac or common AppleScript methods). Ifset text
andappend
are both given, the panel will be cleared, set tomsgText
and then appended withaddText
. Thesave in
argument can be in addition to other arguments or alone to just save the text. Parameters not used in Python can be set toNone
. You also use standard Python and Ruby print commands and their output will be appended to the message window.
This message window can store results of calculations or simply display a message about the current state of a long process. When done, the results can be saved to a file. Since there is only one message panel, you have to be careful other windows will not write to the panel while the script is using it, otherwise some text might might be lost.
Supported By: application (AppleScript only) and documents (all scripts)
Python or Ruby use:MessageAppend_saveIn_setText_(addText,filename,msgText)
RunAnalysis
- Interpret the commands in a commands document and then do the calculations. You can monitor the
processing
property of the front document to find out when the calculations are done. When done, they will appear in a new results document, which will have replaced the commands document as the new front document.
This command will exit as soon as the calculations start. You can monitor theprocessing
attribute of the command document to wait for it to finish.
Warning: This command will create a file in the same folder as the commands file with the same name as the commands file, but with extension ".mpm" or ".fea" for MPM or FEA calculations, respectively. This file will be autosaved after each run, which means it will overwrite any previous file with that same name. To preserve the results, either save the file to a new name or use the RunAnalysisSaving command instead.
Supported By: command documents
Python or Ruby use:RunAnalysis()
RunAnalysisSaving out path (file_path_name) background (True or False)
- This command is the same as the RunAnalysis command, but you provide path name for the output file and optionally tell it to submit as a background process. The path name can be either a full path or a relative path, where relative path is relative to the saved commands file. The parent directory for the output file must already exist. Hint: the user open folder command can be good way to pick a folder and to be sure it exists. When background is
True
, the process will be submitted as a background job and no results will appear in the output window. When it isFalse
, a standard foreground job is submitted and the results can be read from the output results document when they are done.
This command will exit as soon as the calculations start or the background process is submitted. You can monitor theprocessing
attribute of the command document to wait for it to finish; for a background process it is finished once the submittal command is accepted.
Supported By: command documents
Python or Ruby use:RunAnalysisSavingOutPath_background_(file_path_name,False)
SetVariable named varName to value
- Set the variable given by string in
varName
(without the leading '#') to the providedvalue
(value
may be string or a number).
Supported By: command documents
Python or Ruby use:SetVariableNamed_value_(name,value)
time plot plot settings plotOptions
- Plots a selected MPM result as a function of time in a 2D plot document. The result to be plot is determined by the plot settings. See the xy plot command to plot 2D plot of a result through the mesh or mpm grid. Note that the command results before the plot is done. A script will usually need a loop to wait for plot completion. The returned value is a specifier for the new plot document.
Supported By: results documents
Python or Ruby use:timePlotPlotSettings_(plotOptions)
user choice prompt "Prompt Text" list items {"item 1",";item 2"} [title "Panel Title"] [buttons {"OK","Cancel"}] [multiple true]
- Will display a dialog box where the user can select one item from the provided
list items
. To have an item preselected, use a semicolon (";") as the first character (the semicolon will not be displayed). If no item is marked as selected, the first item will be selected. The requiredprompt
is displayed above the list box to explain the requested selection (it can be any length and use multiple lines). The optionaltitle
is displayed in the title bar of the window. The optionalbuttons
can change the text of the default "OK" and "Cancel" buttons and optionally add a third button. The optionalmultiple
parameter can be true or false to allow selection of multiple items (if it is false and more than one item is marked as selected, only the first one will be selected).
The returned result of this command is a list with three items. The first item is the text of the button that was clicked. The second item will be another list with the text of the one or more items selected by the user. The third item will be another list with indices of the one or more items selected by the user (the first item is index=1).
This command can be done with the choose from list command in AppleScript. It is provided in NairnFEAMPM for use in Python or Ruby scripts or as an alternative to the AppleScript version in AppleScripts.
Supported By: application (AppleScript only) and documents (all scripts)
Python/Ruby use:userChoiceListItems_prompt_buttons_multiple_title_(["item 1","item 2","item 3"], "Prompt Text", ["OK","Cancel"], False, "Panel Title")
- use capitalizedTrue
orFalse
in Python, but lowercasetrue
orfalse
in Ruby. user input prompt "Prompt Text" [initial text "default text"] [title "Panel Title"] [buttons {"OK","Cancel"}]
- Will display a dialog box where the user can enter one line of text. The required
prompt
is displayed above the text field to explain the requested input (it can be any length and use multiple lines). The optionalinitial text
is placed in the text field (it can only be a single line). The optionaltitle
is displayed in the title bar of the window. The optionalbuttons
can change the text of the default "OK" and "Cancel" buttons and optionally add a third button. The returned result of this command is a list with two items. The first item is the text of the button that was clicked. The second item is the text entered by the user in the text field.
This command can be done with the display dialog command in AppleScript. It is provided in NairnFEAMPM for use in Python or Ruby scripts or as an alternative to the AppleScript version in AppleScripts.
Supported By: application (AppleScript only) and documents (all scripts)
Python/Ruby use:userInputPrompt_buttons_initialText_title_("Prompt Text", ["OK","Cancel"], "default text", "Panel Title")
user openFile [start "/Users/nairnj/Desktop"] [extensions {"fmcmd", "mpm"}]
- Will display standard MacOS panel for user to select an existing file. The
start
parameter can be used to define the initially selected folder and/or file. Theextensions
list means the user can only select files with those extensions. When done, the command will return the full POSIX path to the selected file (or empty if canceled).
This command can be done with the choose file command in AppleScript. It is provided in NairnFEAMPM for use in Python or Ruby scripts or as an alternative to the AppleScript version in AppleScripts.
Supported By: application (AppleScript only) and documents (all scripts)
Python/Ruby use:userOpenFileExtensions_start_(["fmcmd","mpm"], "/Users/nairnj/Desktop")
user openFolder [start "/Users/nairnj/Desktop"]
- Will display standard MacOS panel for user to select an existing folder or create and select a new folder. The
start
parameter can be used to define the initially selected folder. When done, the command will return the full POSIX path to the selected folder (or empty if canceled).
This command can be done with the choose folder command in AppleScript. It is provided in NairnFEAMPM for use in Python or Ruby scripts or as an alternative to the AppleScript version in AppleScripts.
Supported By: application (AppleScript only) and documents (all scripts)
Python/Ruby use:userOpenFolderStart_("/Users/nairnj/Desktop")
user option title "Main text" [message "Subtitle text"] [buttons {"OK","Cancel"}]
- Will display a dialog box to the user with one to three buttons (provided in the list). The title is in bold and main text of the window. The message appears below the title to provide extra information. The first button is the default button and the buttons appear right to left. The returned result of this command is the text of the clicked button.
This command can be done with the display dialog command in AppleScript. It is provided in NairnFEAMPM for use in Python or Ruby scripts or as an alternative to the AppleScript version in AppleScripts.
Supported By: application (AppleScript only) and documents (all scripts)
Python/Ruby use:userOptionTitle_buttons_message_("Main text", ["OK","Cancel"], "Subtitle text")
user saveFile [start "/Users/nairnj/Desktop"] [extensions {"txt"] [title "Panel Title"]
- Will display standard MacOS panel for selecting file name and location for saving a file. The
start
parameter can be used to define the initially selected folder and/or file name (the file need not exist and you can supply just the name if the start folder is not important). Theextensions
list means the user should save to files with those extensions; if they choose another extension, they will be prompted to use the first extension in the list. Thetitle
parameter is the title at the top for the save file panel. If the selected file already exists, the user will be asked to confirm that it is OK to replace that file. When done, the command will return the full POSIX path to the selected file (or empty if canceled).
This command can be done with the choose file name command in AppleScript. It is provided in NairnFEAMPM for use in Python or Ruby scripts or as an alternative to the AppleScript version in AppleScripts.
Supported By: application (AppleScript only) and documents (all scripts)
Python/Ruby use:userSaveFileExtensions_start_title_(["txt"], "/Users/nairnj/Desktop", "Panel Title")
xy plot plot settings plotOptions
- Plots a selected MPM or FEA result as a function of position in a 2D plot document. The result to be plotted is determined by the plot settings. See the time plot command to plot an MPM result as a function of time. Note that the command results before the plot is done. A script will usually need a loop to wait for plot completion. The returned value is a specifier for the new plot document.
Supported By: results documents
Python or Ruby use:xyPlotPlotSettings_(plotOptions)
Plotting Results in Script Control
The time plot and xy plot commands plot selected results to a 2D plot document. The script can read the data in the results plot for more calculations. The plot that is generated depends on the the command's plotOptions
argument. The current options, which are case insensitive, are:
- Quantity to Plot (all plots):
menutext
- quantity by name in plot menu (string, case sensitive)plotindex
- quantity by index in plot menu (number from 0)component
- quantity by tag (number used in code)tensorindex
- select component of tensor to plot (number from 0)vectorindex
- select component of vector to plot (number from 0)angle
- rotate vector or tensor (in degrees)expression
- enter an valid expression to plot (string)expressiontitle
- enter a title a plotted expression (string)
- Extra options for time plots:
quantity
- whenmenutext
is "Global Results", this value is the global quantity, by name, to plot. Note that first item in returned list is the plotted quantity and the values start at the second item.materialoption
- plot the provide point number (0), average all points (1), average the provided material number (2), sum all points (3), or sum the provided material number (4)initialpoint
- point number to plot whenmaterialoption
= 0.materialnumber
- material number to average whenmaterialoptoin
= 2 or 4.cracknumber
- crack number to plottipnumber
- crack tip to plot for start (0) or end (1).
- Extra options for xy plots:
archive
- select time to plot by archive index (numbered from 1)variable
- plot option (by number) for path though the mesh as 0: x or r, 1: y or z, 2: D, 3: T, 4: p:x+d*t, 5: p0:x0+d*t, or 6: Histogramcontour
- an expression for the plot contour (string even if just a number). For particle plots can be comma separated list of 1 to 6 numbers as needed.contourrange
- range (+/-) to average along the contour (number)cracknumber
- crack number to plot
- Script control:
- proceed - true to generate the plot; if false, the software will stop for more user input in the plot dialog box. This parameter is automatically set to "true" when called from an internal script.
- close - internal scripts close the window after the plot is done unless this key is set to "no" (only used by internal scripts).
- superpose - with any value, the next plot is superposed on the same type of plot from the same document (if available and only used by internal scripts).
The plotting command will return to the script befefore the plot is done. If your want to access the data in the script, you will need to create a loop that waits for the command to finish. The following templates prepare a dictionary, call the plot command, and then tell the new plot document to wait until the plot is completed. Once the plot is done, properties of the new plot document are probed to get x-y data points for the plot. See the NairnFEAMPM AppleScript dictionary for details on properties of plot documents.
An AppleScript plotting template is as follows:
-- plot the data tell front results document set plotOptions to (a dictionary of opions) set pdoc to time plot plot settings plotOptions end tell tell front plot document -- wait for plot to finish repeat while plotting is true end repeat -- read plot data tell last plot set xyData to plot data end tell end tell
A template for plotting in Python is as follows:
# plot the data plotOptions = {a dictionary of options} pdoc = rdoc.xyPlotPlotSettings_(plotOptions) # wait for the plot to finish while pdoc.plotting() == True : time.sleep(1.) # get last plot data plots = pdoc.plots() numPlots = plots.count() plot = plots.objectAtIndex_(numPlots-1) xyData = plot.plotData()