Introduction
- Need to come up with a good introduction
- Discuss that this guide will focus on the AWR SDE but you can connect to the COM API in many languages.
Important Resources
- Sax Basic function help document. https://awrcorp.com/download/kb.aspx?file=/Questions/NI_AWR_Sax_Basic.pdf
- AWR documentation page https://awrcorp.com/download/faq/english/docs/ApiReference/sde.html
- AWR API UML Diagram https://awrcorp.com/download/kb.aspx?file=11_scripts/AWR_2010_API_Diagram.pdf (note, asked Dave for an updated version of this for V13).
- Shipping AWR Scripts as Examples http://kb.awr.com/x/i4dd
- Scripting KB http://kb.awr.com/x/5oRd
My First Script
This first script will be a very simple script to show you the Scripting Development Environment (SDE) built into the NI AWR Design Environment.
Start the NI AWR Design Environment
The AWR SDE is launched from within the NI AWR Design Environment. Your first step is to start the NI AWR Design Environment. Save the project to a file named MyFirstScript to help follow along exactly with this guide.
Opening the SDE
From the menus, select Tools > Scripting Editor.
Alternately, you can use the hotkeys Alt+F11 or click on the Scripting Editor toolbar.
A new window titled AWR Scripting will open which is the AWR SDE.
Creating a New Code Module
From the SDE Project browser, right click over the MyFirstScript.emp node and select Insert Module
A new module is added named Module1 under the Code Modules node in the project The code module window will also open for editing. You might need to maximize this window to see the full contents. Notice the starting Sub Main and End Sub code is added for you.
Adding the Code
In the open code module, type "msgbox(" as shown below
Notice as soon as you type the open parenthesis, information displays about the inputs to the function. The first input is the message to display in the message box. The second two are optional to set the type of message box and the title of the message box.
Now finish the rest of the line so that it reads "msgbox("Hello World")"
Running the Code
Your code is ready to run. To run the code, use the Run toolbar as shown below.
When you run this code, you will see a message box display as shown below.
Congratulations, you have created and run your first script!
Creating a Filter Simulation
The section will cover creating a script to create the same circuit as in the linear chapter of the Microwave Office getting started guide. In general this will work through the various steps of creating the filter. The code will be structured as each step will be a Function or Sub Routine in the Sub Main. The guide will shown you how to change the Sub Main and then just the code to implement that Function of Subroutine. This will make showing the code changes at each step simpler.
Create a New Project
Either start a new project or select File > New Project. Then save the project with the name ScriptFilter.emp.
Clean Up Code
When developing scripts, it is common that the script will change your project. It is a good idea to have code to clean up the project while you are developing this script. This saves many mouse clicks of doing manual clean up. For this example, create a new code module. Right click on the code module, select Rename 'Module1'...
Then type CleanUp in the dialog that opens.
Copy the code below into the module.
Sub Main Dim s As Schematic Dim g As Graph Dim opt As OptGoals For Each s In Project.Schematics Project.Schematics.Remove(s.Name) Next s For Each g In Project.Graphs Project.Graphs.Remove(g.Name) Next g Project.OptGoals.RemoveAll MWOffice.Windows.Close End Sub
Create Schematic
Create a new code module and rename it to "Filter"
The code is shown below. We recommend you type the code to get used to typing and viewing the autocomplete.
' Code Module Sub Main Dim sch As Schematic Set sch = CreateSchematic End Sub Function CreateSchematic() As Schematic Set CreateSchematic = Project.Schematics.Add("lpf") End Function
For the autocomplete, when you type "project.", you will get a list of the available objects available under the Project object.
As you continue typing, it will match the closest and will be highlighted. For example, typing "project.sch" will show as below.
Notice the next object that is highlighted. If you press the Tab key, that object is completed.
Now, if you run this code, a new schematic is added.
See that a new schematic was added the new blank schematic window is opened.
Note: if you run the script again, a new schematic will be created with a slightly different name.
The CreateScheamtic code was done as a function to be able to send up an object for the schematic created. This is important in case you do create objects by name that already exist, you can reference the schematic exactly as created this way.
At this point, you want to run the CleanUp script to remove these schematics before going to the next step.
To make things easier, the CleanUp code will be run before any other code is run. The main subroutine should now look like below:
' Code Module Sub Main Dim sch As Schematic CleanUp Set sch = CreateSchematic End Sub
Then add the cleanup code after the sub main subroutine.
Sub CleanUp Dim s As Schematic Dim g As Graph Dim opt As OptGoals For Each s In Project.Schematics Project.Schematics.Remove(s.Name) Next s For Each g In Project.Graphs Project.Graphs.Remove(g.Name) Next g Project.OptGoals.RemoveAll MWOffice.Windows.Close End Sub
Now, you can run the code over and over and you will not get multiple schematics.
One final piece to help the development step is to add code to arrange windows and zoom the schematic.
The main subroutine should now look like below:
' Code Module Sub Main Dim sch As Schematic CleanUp Set sch = CreateSchematic ArrangeWindows End Sub
Then add the window arranging code after the sub main subroutine.
Sub ArrangeWindows Dim w As Window For Each w In MWOffice.Windows If w.Caption = "lpf" Then w.ViewAll End If Next w MWOffice.Windows.Tile(mwWTD_Vertical) End Sub
Now when you run the code, the schematic will be maximized.
Add Elements to the Schematic
Next, we need to build the schematics. This involves adding elements, wires, ports and ground nodes.
The main subroutine should now look like below:
Sub Main Dim sch As Schematic CleanUp Set sch = CreateSchematic BuildSchematic(sch) ArrangeWindows End Sub
Then type or add the schematic building code after the sub main subroutine. Notice that wires are not needed between each element. When element nodes overlap, they are automatically connected.
Sub BuildSchematic(s As Schematic) 'add inductors 'each visible grid in the schematic has a value of 100 for the coordinates s.Elements.Add("IND",0,0) s.Elements.Add("IND",1000,0) s.Elements.Add("IND",2000,0) s.Elements.Add("IND",3000,0) 'add capacitors s.Elements.Add("CAP",1000,0,270) s.Elements.Add("CAP",2000,0,270) s.Elements.Add("CAP",3000,0,270) 'add wire s.Wires.Add(1000,1000,3000,1000) 'add ports s.Elements.Add("PORT",0,0) s.Elements.Add("PORT",4000,0,180) 'add ground s.Elements.Add("GND",1000,1000) End Sub
This is a subroutine because no information is passed out of the code when it is completed. We do pass in the schematic object just in case there were naming issues as previously discussed.
After this point, you will see this schematic in a window that is maximized and centered around the elements.
Change Parameter Values
Next, we need to change parameter values in the already created elements. This could have been done at the same time as adding the elements. it was done this way to more closely follow the same steps of creating the filter by hand.
The main subroutine should now look like below:
Sub Main Dim sch As Schematic CleanUp Set sch = CreateSchematic BuildSchematic(sch) SetValues(sch) ArrangeWindows End Sub
Then type or add the frequency changing code after the sub main subroutine. A few things to notice.
- The elements are referenced by the element name, a dot, and then the ID of the element.
- The values are set in base units, such as Hz, Henry's, Farads, etc. This is because each project could have different project units but the code will still work just fine. The schematic display converts to the proper units.
Sub SetValues(s As Schematic) 'sets the parameter values of the elements to be non-default 'values as double will always be in base units (Farads, Henries, etc) s.Elements("IND.L1").Parameters("L").ValueAsDouble = 15e-9 s.Elements("IND.L2").Parameters("L").ValueAsDouble = 30e-9 s.Elements("IND.L3").Parameters("L").ValueAsDouble = 30e-9 s.Elements("IND.L4").Parameters("L").ValueAsDouble = 15e-9 s.Elements("CAP.C1").Parameters("C").ValueAsDouble = 8e-12 s.Elements("CAP.C2").Parameters("C").ValueAsDouble = 10e-12 s.Elements("CAP.C3").Parameters("C").ValueAsDouble = 8e-12 End Sub
After this point, you will see this schematic in a window that is maximized and centered around the elements with new parameter values.
Change Frequencies
Next, we need to change the simulation frequencies as the defaults of 1 and 2 GHz would not result in meaningful simulation results. If you select Options > Project Options from the Microwave Office menus, the frequency list is displayed, this is to show the frequencies before the change.
The main subroutine should now look like below:
Sub Main Dim sch As Schematic CleanUp Set sch = CreateSchematic BuildSchematic(sch) SetValues(sch) SetFrequencies ArrangeWindows End Sub
Then type or add the frequency setting code after the sub main subroutine. A few things to notice.
- We must clear the previous frequencies.
- We are creating an array of doubles, filling in the array and then only doing one call to set the frequencies. This is the fast way to implement these changes.
Sub SetFrequencies Dim freqs() As Double fstart = 100 fstop = 1000 fstep = 10 num = (fstop-fstart)/fstep ReDim freqs(num) Project.Frequencies.Clear cnt = 0 For i = 100 To 1000 Step 10 freqs(cnt) = i * 1e6 'enter in base units, Hz. cnt = cnt + 1 Next i Project.Frequencies.AddMultiple(freqs) End Sub
When the code is run, you can check the frequencies again to see they have changed.
As an aside, the simpler code to add frequencies is below. It is much simpler but much slower to execute due to all the calls to add frequencies.
Sub SetFrequencies Project.Frequencies.Clear For i = 100 To 1000 Step 10 Project.Frequencies.Add(i * 1e6) 'enter in base units, Hz. Next i End Sub
Add Graph
Next, we need to add a graph and some measurements to the graph.
The main subroutine should now look like below:
Sub Main Dim sch As Schematic CleanUp Set sch = CreateSchematic BuildSchematic(sch) SetValues(sch) SetFrequencies AddGraph(sch) ArrangeWindows End Sub
Then type or add the graph and measurement code after the sub main subroutine. A few things to notice.
- The intellisence will help you get the right setting for the graph type.
- We pass in the schematic so we can get the schematic name as the first argument for the measurement.
- The measurements have a very specific syntax. An easy way to get this is to add the measurement to a project and then use a script to retrieve the measurement syntax.
Sub AddGraph(s As Schematic) Dim g As Graph Set g = Project.Graphs.Add("s21 and s11",mwGT_Rectangular) g.Measurements.Add(s.Name,"DB(|S(1,1)|)") g.Measurements.Add(s.Name,"DB(|S(2,1)|)") End Sub
When the code is run, you will have your schematic and graph tiled.
Simulate
Next, we need to add a graph and some measurements to the graph.
The main subroutine should now look like below:
Sub Main Dim sch As Schematic CleanUp Set sch = CreateSchematic BuildSchematic(sch) SetValues(sch) SetFrequencies AddGraph(sch) Simulate ArrangeWindows End Sub
Then type or add the simulate code after the sub main subroutine. It is a little silly to add a one-line subroutine. It was done this way for consistency with the rest of the steps.
Sub Simulate Project.Simulator.Analyze End Sub
When the code is run, you will have your schematic and graph tiled now with simulation results.
Adding Markers
Next, we need to add a markers to the traces to help find the 3dB roll-off frequency
The main subroutine should now look like below:
Sub Main Dim sch As Schematic CleanUp Set sch = CreateSchematic BuildSchematic(sch) SetValues(sch) SetFrequencies AddGraph(sch) Simulate AddMarkers(sch) ArrangeWindows End Sub
Then type or add the marker adding code after the sub main subroutine. A few things to notice.
- We used Marker objects to change properties of the markers once they were added.
- The measurement is referenced by its entire string, the schematic passed in gives the name and then the measurement is added by concatonating strings using the & operator.
Sub AddMarkers(s As Schematic) Dim m As Marker Dim m2 As Marker Set m = Project.Graphs(1).Markers.Add(s.Name & ":DB(|S(2,1)|)",1,0.1e9) m.Type = mwMT_AutoSearch m.AutoSearch.mode=mwMAM_Max Set m2 = Project.Graphs(1).Markers.Add(s.Name & ":DB(|S(2,1)|)",1,0.5e9) m2.Type =mwMT_Offset m2.Offset.Distance = -3 m2.Offset.mode=mwMOM_Y m2.Offset.ReferenceMarker="m1" End Sub
When the code is run, you will have your schematic and graph tiled now with simulation results and markers. You can now read the 3D roll-off frequency from the "m2" marker.
Adding Equations
Next, we need to add equations and assign some parameters to use these equations. We know the filter needs to be symmetric and this is one way to create this symmetry.
The main subroutine should now look like below:
Sub Main Dim sch As Schematic CleanUp Set sch = CreateSchematic BuildSchematic(sch) SetValues(sch) SetFrequencies AddGraph(sch) Simulate AddMarkers(sch) AddEquations(sch) ArrangeWindows End Sub
Then type or add the equation adding code after the sub main subroutine. A few things to notice.
- Equations are similar to adding elements with the location. However, you enter the exact equation syntax, equations don't have a concept of units.
- When assigning parameters to equations, we use the .ValueAsString command.
Sub AddEquations(s As Schematic) 'add equations and assign parameters to use the equation. s.Equations.Add("IND=15",1500,-1000) s.Equations.Add("CAP=8",2500,-1000) s.Elements("IND.L1").Parameters("L").ValueAsString = "IND" s.Elements("IND.L4").Parameters("L").ValueAsString = "IND" s.Elements("CAP.C1").Parameters("C").ValueAsString = "CAP" s.Elements("CAP.C3").Parameters("C").ValueAsString = "CAP" End Sub
After this point, you will see this schematic in a window that is maximized and centered around the elements with the new equations.
Setting Optimization Parameters and Limits
Next, we need to set up the parameters we want to optimize and set optimization limits. The best way to see the before and after is to open the variable browser, View > Variable Browser.
The main subroutine should now look like below:
Sub Main Dim sch As Schematic CleanUp Set sch = CreateSchematic BuildSchematic(sch) SetValues(sch) SetFrequencies AddGraph(sch) Simulate AddMarkers(sch) AddEquations(sch) OptLimits(sch) ArrangeWindows End Sub
Then type or add the optimization variables and limits code after the sub main subroutine. A few things to notice.
- If we don't set the .Constrain=True, then the limits won't matter.
- the goal was to set the lower and upper limits 25% of the nominal value. The code cheats a bit as we know the parameter values from previous steps. It would be cleaner to get the parameter value and then apply the percentages.
Sub OptLimits(s As Schematic) 'setup various values for optimization including constraints. s.Equations("CAP").Optimize=True s.Equations("CAP").Constrain=True s.Equations("CAP").LowerConstraint = 8*0.75 s.Equations("CAP").UpperConstraint = 8*1.25 s.Equations("IND").Optimize=True s.Equations("IND").Constrain=True s.Equations("IND").LowerConstraint = 15*0.75 s.Equations("IND").UpperConstraint = 15*1.25 s.Elements("CAP.C2").Parameters("C").Optimize=True s.Elements("CAP.C2").Parameters("C").Constrain=True s.Elements("CAP.C2").Parameters("C").LowerConstraint = 10*0.75*1e-12 s.Elements("CAP.C2").Parameters("C").UpperConstraint = 10*1.25*1e-12 End Sub
If you check the variable view again after this code, it will look like below.
Adding Optimization Goals
Next, we need to add the optimization goals.
The main subroutine should now look like below:
Sub Main Dim sch As Schematic CleanUp Set sch = CreateSchematic BuildSchematic(sch) SetValues(sch) SetFrequencies AddGraph(sch) Simulate AddMarkers(sch) AddEquations(sch) OptLimits(sch) SetOptGoals(sch) ArrangeWindows End Sub
Then type or add the optimization goals code after the sub main subroutine. The syntax is a bit involved. This usually takes a little trial and error to get it right.
Sub SetOptGoals(s As Schematic) Project.OptGoals.Add(s.Name,"DB(|S(1,1)|)",mwOGT_LessThan,1,2,0,500e6,mwUT_Frequency,-17,-17,mwUT_DB) Project.OptGoals.Add(s.Name,"DB(|S(2,1)|)",mwOGT_GreaterThan,1,2,0,500e6,mwUT_Frequency,-1,-1,mwUT_DB) Project.OptGoals.Add(s.Name,"DB(|S(2,1)|)",mwOGT_LessThan,1,2,700e6,1000e6,mwUT_Frequency,-30,-30,mwUT_DB) End Sub
When the code is run, you will have your schematic and graph tiled now with simulation results and see the optimization goals on the graph.
Optimize
Next, we will optimize the circuit.
The main subroutine should now look like below:
Sub Main Dim sch As Schematic CleanUp Set sch = CreateSchematic BuildSchematic(sch) SetValues(sch) SetFrequencies AddGraph(sch) Simulate AddMarkers(sch) AddEquations(sch) OptLimits(sch) SetOptGoals(sch) ArrangeWindows Optimize End Sub
Notice the Optimization step is coming before arranging the windows. This will be so you can have nice arrangement while watching the optimization happen.
Then type or add the optimization goals code after the sub main subroutine. A few things to notice.
- There is a helper function that helps set the optimizer type. The type is set by integer and not name, so the function finds the name and returns the integer. Different versions of the software can change the order or number of optimizers, so this is the best way to ensure the right optimizer is used.
- There is a loop to wait for the optimizer to be done as we don't know in the code how long this will take.
Sub Optimize Project.Optimizer.MaxIterations = 500 Project.Optimizer.Type = find_opt_type("Random (Local)") Project.Optimizer.NewWindow Project.Optimizer.Start While Project.Optimizer.Running=True Wait(0.5) Wend End Sub Function find_opt_type(nm As String) As Integer Dim typ As Integer typ = -1 For i = 1 To Project.Optimizer.TypeCount If nm = Project.Optimizer.TypeName(i) Then typ = i End If Next i If typ = -1 Then MsgBox ("could not find optimizer name specified:" & nm) End If find_opt_type = typ End Function
When the code is run, you will have your schematic and graph tiled now with simulation results and the optimization running with the optimizaiton window opened.
Script Complete
Since the optimization will take some time, you can display a message box when it is done.
The main subroutine should now look like below:
Sub Main Dim sch As Schematic CleanUp Set sch = CreateSchematic BuildSchematic(sch) SetValues(sch) SetFrequencies AddGraph(sch) Simulate AddMarkers(sch) AddEquations(sch) OptLimits(sch) SetOptGoals(sch) ArrangeWindows Optimize MsgBox("Your Filter Optimization is Complete") End Sub
When the script is done, you will see the message box shown below.
Some Topics to Think About
Option Explicit
Forces all variables used to be defined and properly typed. VB is not strongly typed so it's easy to get "spaghetti" code going. This helps to cut down on it. Also helps the user instantly find typos in variable names.Option Explicit
F1 Help
When the cursor is in a word in the scripting editor, type the F1 button for help on that keyword. F1 Help in Scripting
Dictionaries
Dictionaries are an incredibly useful concept when working with visual basic. They are a great way collect up lists of items, especially if you don't know how many items you will need to have in your list. You can think of a dictionary exactly like a classic dictionary, there are two pieces of information. In the classic dictionary there is a word and then the definition. In the dictionary object, there is a key and an item. The key is the word, and the item is the definition. Please see the article for details on using dictionaries. Scripting How-To: Using a Dictionary in AWR Scripting
File System Objects
The file system objects allow working with files and folders very easily. For example, if you need to process a folder and all subfolders and look for files, these utilities make that very easy. Please see the article for details on using file system objects. Scripting How-To: File System Objects and Scripting How-To:How Can I Easily Scan Drives, Directories, Files in a Directory, and Perform Basic File Operations
Browse to a File
A simple command to get a dialog to box to ask the user to browse to a file. Scripting How-To: Using GetFilePath
Browse to a Folder
Not as simple, but sometimes you want to get a folder location instead of a file location. Scripting How-To: How to Prompt for a Folder in AWR Scripting
Adding a Form
You may need to build a custom dialog for your script. This is made easy by having a graphical user interface to build your dialog. Scripting How-To: Adding a Custom Dialog
The Dialog Function
The dialog function allows for advanced dialog functionality such as initializing the state of the dialog, changing if items are enabled or not based on other actions, keeping the dialog open as commands are performed, etc. Scripting How-To:Generating S-Parameter files from AWR Scripting and Scripting How-To: Creating a Dialog with Status Text and a Progress Bar in AWR Scripting. Some shipping scripts also heavily use the dialog function, Generate MDIF from Collection of Files and Modify Graph Properties
Referencing other modules
You may want to reference other code modules for shareable code, there are various ways to do this. Scripting How-To: Referencing Subs and Functions in Other Files
Python
The examples so far have shown working with the AWR SDE. Python is a common scripting language and could also be used to accomplish the same tasks. Please see <> for more details. The exact same code to complete the same tasks in python is shown below.
# -*- coding: utf-8 -*- "Connecting to MWO" import win32com.client as win32 import time def Cleanup(): for s in awr.Project.Schematics: awr.Project.Schematics.Remove(s.Name) for g in awr.Project.Graphs: awr.Project.Graphs.Remove(g.Name) awr.Project.OptGoals.RemoveAll awr.Windows.Close def CreateSchematic(): s=awr.Project.Schematics.Add("lpf") return s def BuildSchematic(s): "add inductors" "each visible grid in the schematic has a value of 100 for the coordinates" awr.Project.Schematics(s.Name).Elements.Add("IND",0,0) awr.Project.Schematics(s.Name).Elements.Add("IND",1000,0) awr.Project.Schematics(s.Name).Elements.Add("IND",2000,0) awr.Project.Schematics(s.Name).Elements.Add("IND",3000,0) "add capacitors" awr.Project.Schematics(s.Name).Elements.Add("CAP",1000,0,270) awr.Project.Schematics(s.Name).Elements.Add("CAP",2000,0,270) awr.Project.Schematics(s.Name).Elements.Add("CAP",3000,0,270) "add wire" awr.Project.Schematics(s.Name).Wires.Add(1000,1000,3000,1000) "add ports" awr.Project.Schematics(s.Name).Elements.Add("PORT",0,0) awr.Project.Schematics(s.Name).Elements.Add("PORT",4000,0,180) "add ground" awr.Project.Schematics(s.Name).Elements.Add("GND",1000,1000) def SetValues(s): "sets the parameter values of the elements to be non-default" "values as double will always be in base units (Farads, Henries, etc)" awr.Project.Schematics(s.Name).Elements("IND.L1").Parameters("L").ValueAsDouble = 15e-9 awr.Project.Schematics(s.Name).Elements("IND.L2").Parameters("L").ValueAsDouble = 30e-9 awr.Project.Schematics(s.Name).Elements("IND.L3").Parameters("L").ValueAsDouble = 30e-9 awr.Project.Schematics(s.Name).Elements("IND.L4").Parameters("L").ValueAsDouble = 15e-9 awr.Project.Schematics(s.Name).Elements("CAP.C1").Parameters("C").ValueAsDouble = 8e-12 awr.Project.Schematics(s.Name).Elements("CAP.C2").Parameters("C").ValueAsDouble = 10e-12 awr.Project.Schematics(s.Name).Elements("CAP.C3").Parameters("C").ValueAsDouble = 8e-12 def ArrangeWindows(): for i in range(awr.Windows.Count): awr.Windows(i+1).ViewAll() awr.Windows.Tile(1) def SetFrequencies(): freqs=[] awr.Project.Frequencies.Clear for i in range(100, 1000, 10): freqs.append(i*1e6) awr.Project.Frequencies.AddMultiple(freqs) def AddGraph(s): g = awr.Project.Graphs.Add("s21 and s11",3) g.Measurements.Add(s.Name,"DB(|S(1,1)|)") g.Measurements.Add(s.Name,"DB(|S(2,1)|)") def Simulate(): awr.Project.Simulator.Analyze() def AddMarkers(s): m = awr.Project.Graphs(1).Markers.Add(s.Name + ":DB(|S(2,1)|)",1,0.1e9) m.Type = 3 m.AutoSearch.mode=0 m2 = awr.Project.Graphs(1).Markers.Add(s.Name + ":DB(|S(2,1)|)",1,0.5e9) m2.Type =4 m2.Offset.Distance = -3 m2.Offset.mode=1 m2.Offset.ReferenceMarker="m1" def AddEquations(s): awr.Project.Schematics(s.Name).Equations.Add("IND=15",1500,-1000) awr.Project.Schematics(s.Name).Equations.Add("CAP=8",2500,-1000) awr.Project.Schematics(s.Name).Elements("IND.L1").Parameters("L").ValueAsString = "IND" awr.Project.Schematics(s.Name).Elements("IND.L4").Parameters("L").ValueAsString = "IND" awr.Project.Schematics(s.Name).Elements("CAP.C1").Parameters("C").ValueAsString = "CAP" awr.Project.Schematics(s.Name).Elements("CAP.C3").Parameters("C").ValueAsString = "CAP" def OptLimits(s): awr.Project.Schematics(s.Name).Equations("CAP").Optimize=True awr.Project.Schematics(s.Name).Equations("CAP").Constrain=True awr.Project.Schematics(s.Name).Equations("CAP").LowerConstraint = 8*0.75 awr.Project.Schematics(s.Name).Equations("CAP").UpperConstraint = 8*1.25 awr.Project.Schematics(s.Name).Equations("IND").Optimize=True awr.Project.Schematics(s.Name).Equations("IND").Constrain=True awr.Project.Schematics(s.Name).Equations("IND").LowerConstraint = 15*0.75 awr.Project.Schematics(s.Name).Equations("IND").UpperConstraint = 15*1.25 awr.Project.Schematics(s.Name).Elements("CAP.C2").Parameters("C").Optimize=True awr.Project.Schematics(s.Name).Elements("CAP.C2").Parameters("C").Constrain=True awr.Project.Schematics(s.Name).Elements("CAP.C2").Parameters("C").LowerConstraint = 10*0.75*1e-12 awr.Project.Schematics(s.Name).Elements("CAP.C2").Parameters("C").UpperConstraint = 10*1.25*1e-12 def SetOptGoals(s): awr.Project.OptGoals.Add(s.Name,"DB(|S(1,1)|)",1,1,2,0,500e6,1,-17,-17,15) awr.Project.OptGoals.Add(s.Name,"DB(|S(2,1)|)",2,1,2,0,500e6,1,-1,-1,15) awr.Project.OptGoals.Add(s.Name,"DB(|S(2,1)|)",1,1,2,700e6,1000e6,1,-30,-30,15) def Optimize(): awr.Project.Optimizer.MaxIterations = 500 awr.Project.Optimizer.Type = find_opt_type("Random (Local)") awr.Project.Optimizer.NewWindow() awr.Project.Optimizer.Start() while awr.Project.Optimizer.Running == True: time.sleep(0.5) def find_opt_type(nm): typ = -1 for i in range(awr.Project.Optimizer.TypeCount): if nm == awr.Project.Optimizer.TypeName(i+1): typ = i+1 if typ == -1: print ("could not find optimizer name specified:" + nm) return typ "main program" awr = win32.Dispatch("MWOApp.MWOffice") Cleanup() sch = CreateSchematic() BuildSchematic(sch) SetValues(sch) SetFrequencies() AddGraph(sch) Simulate() AddMarkers(sch) AddEquations(sch) ArrangeWindows() OptLimits(sch) SetOptGoals(sch) Optimize()