This article shows how to start Speos using a batch and load a Python script. These tips will, for example, enable users to automate starting and ending Speos and perform calculations in headless mode or send arguments from a batch file to python.
Overview
Using Python scripts combined with batch files in Ansys Speos is essential for automating tasks, enhancing efficiency, and ensuring repeatable processes. Python scripts handle design modifications, simulations, and file saving, while batch files automate execution with useful options to facilitate logging, and workflow customization. An Ansys Speos process can also be deployed in headless mode using a batch file, enhancing performance in multiple ways. Below some of the expected outcomes:
- Resource Efficiency: Headless mode consumes fewer system resources as it doesn't require a graphical user interface (GUI), allowing more resources for computation.
- Automation: It facilitates automation of tasks, enabling scripts to run without manual intervention, which is ideal for batch processing.
- Remote Execution: Operations can be performed on remote servers where a GUI may not be available or necessary.
- Speed: Without rendering graphics, processes may execute faster, improving performance for certain tasks.
- Stability: Reduces the chance of errors or crashes related to the graphical interface, enhancing reliability.
The process can be simplified into 2-3 different steps:
To give an illustrative example, the following sections will show how to create a reflector, compute a simulation, and retrieve the results.
The process can be simplified as below: from a batch file a new Ansys Speos process is started. From the same bat file, it is possible to define the location of a python script with all the Speos instructions to load it and execute it in Ansys Speos.
Creating and Executing the Scripts
Step 1: Create the python script.
- Tips.
The main goal of this step is creating a python file with all the Speos or SpaceClaim instructions. Remember that Speos compiler uses IronPython, so some of the external libraries might not be compatible with these methods.
IronPython is an open-source version of the Python programming language, closely integrated with the .NET Framework. It allows you to use both .NET Framework and Python libraries and enables other .NET languages to seamlessly use Python code.
Currently, on Speos 2024R2, the IronPython version is 2.7.4, and not all libraries are compatible with it. It is strongly recommended to check the compatible libraries if you are planning to import specific libraries.
To create the script, you can support yourself on the record tool of the script editor. Click on insert selection mode and choose “Index”. Then, make sure that the record button is enabled.
- Basic Python Script.
The basic structure of the script can be divided into 5 different sections.
- Define the file path of the .scdocx project.
- Import the project.
- Make modifications in the design, material, sensor or simulation properties.
- Compute a simulation.
- Save the project.
To run the example locally, no modifications are required, as the path defined in line 3 os.getcwd() refers to the current directory of the batch. The batch and Python files must be in the same folder, or you can modify line 3 accordingly.
import os
# Variables
path = os.getcwd()
filename = "Start.scdocx"
filepath = os.path.join(path, filename)
# Import project
importOptions = ImportOptions.Create()
DocumentOpen.Execute(filepath, importOptions)
# Update Reflector
Reflector = SpeosDes.RectangularSurface.Find("Optical Surface Rectangular.1")
Reflector.Groups[0].XRadius = 5
Reflector.Groups[0].YRadius = 5
Reflector.Compute()
# Update Simulation
dummySimu = SpeosSim.SimulationDirect.Find("Dummy_Simulation")
dummySimu.Compute()
# Save File
options = ExportOptions.Create()
DocumentSave.Execute(os.path.join(path, "End.scdocx"), options)
- Python Script with Exceptions.
To make sure the script is working correctly under all circumstances it is recommended to use Try/except/finally blocks.
Using “try” in the areas where the code could raise an exception, allows to handle the exception and continue running or gracefully exit, while it improves the clarity, maintenance and robustness of the code.
Thus, updating the code:
import os
# Variables
path = os.getcwd()
filename = "Start.scdocx"
filepath = os.path.join(path, filename)
try:
print("# Starting Process")
# Import project
importOptions = ImportOptions.Create()
DocumentOpen.Execute(filepath, importOptions)
# Update Reflector
Reflector = SpeosDes.RectangularSurface.Find("Optical Surface Rectangular.1")
Reflector.Groups[0].XRadius = 5
Reflector.Groups[0].YRadius = 5
Reflector.Compute()
# Update Simulation
dummySimu = SpeosSim.SimulationDirect.Find("Dummy_Simulation")
dummySimu.Compute()
# Save File
options = ExportOptions.Create()
DocumentSave.Execute(os.path.join(path, "End.scdocx"), options)
except Exception as err:
print("Unexpected "+str(err)+", "+str(type(err)))
finally:
print("DONE")
Step 2: Log the python script.
- Log the Python Script (Optional).
Logging is essential and highly recommended, especially when deploying this process in headless mode, as it provides the most straightforward method for identifying coding errors, incompatibilities, or other anomalies. Logs offer valuable insights into the application's behavior, aiding in debugging by exposing issues without relying on a user interface. By capturing errors and exceptions, logs streamline problem diagnosis, ensuring smoother operation.
While you can log using Python’s built-in “logging” library, for simplicity, we’ll define an output file to capture all Python “print” statements. This requires adjustments to the batch file, adding the /ScriptOutput configuration parameter. The setup is detailed in the next section.
The following script demonstrates how to create a log file in the project folder, tracking project import, OS modifications, feature status, and the progress and status of the simulation computation.
import os
# Variables
path = os.getcwd()
filename = "Start.scdocx"
filepath = os.path.join(path, filename)
try:
print("Process Started...")
# Import project
importOptions = ImportOptions.Create()
print("Importing project...")
DocumentOpen.Execute(filepath, importOptions)
print("Project imported.")
# Update Reflector
print("Finding reflector...")
Reflector = SpeosDes.RectangularSurface.Find("Optical Surface Rectangular.1")
print("Reflector Status = " + str(Reflector.StatusInfo))
print("Parameters before modifications:")
print("XRadius = " + str(Reflector.Groups[0].XRadius))
print("YRadius = " + str(Reflector.Groups[0].YRadius))
Reflector.Groups[0].XRadius = 5
Reflector.Groups[0].YRadius = 5
Reflector.Compute()
print("Reflector's Status after compute = " + str(Reflector.StatusInfo))
print("Parameters after modifications:")
print("XRadius = " + str(Reflector.Groups[0].XRadius))
print("YRadius = " + str(Reflector.Groups[0].YRadius))
# Update Simulation
print("Finding Simulation...")
dummySimu = SpeosSim.SimulationDirect.Find("Dummy_Simulation")
print("Object = " + str(dummySimu))
print("Simulation Status before compute = " + str(dummySimu.StatusInfo))
dummySimu.Compute()
print("Simulation Status after compute = " + str(dummySimu.StatusInfo))
# Save File
options = ExportOptions.Create()
DocumentSave.Execute(os.path.join(path, "End.scdocx"), options)
except Exception as err:
print("Unexpected error: \n"+str(err)+", "+str(type(err)))
finally:
print("Process finished.")
Step 3: Create the batch script.
- Create the batch file.
Finally, you need to create a .bat calling the Speos launcher and loading the python script on it. To do this, define the bin folder in the installation directory (by default: C:/Program Files/ANSYS Inc/v242/Optical Products/Speos/bin/) and the working path as it follows:
REM Set the root directory to the location of the Speos executable
set root=C:/Program Files/ANSYS Inc/v242/Optical Products/Speos/bin/
REM Set the working directory to the directory of the script
set WORKING_DIR=%~dp0
REM Run the Speos Launcher with the following parameters
"%root%AnsysSpeosLauncher.exe" ^
/RunScript="%WORKING_DIR%Python_with_log.py" ^
/ScriptOutput="%WORKING_DIR%Speos_log.txt" ^
/ExitAfterScript=True ^
/Headless=True ^
/Splash=True ^
/UseCurrentDirectory=True
Then you only need to execute “Ansys Speoslauncher.exe” adding the script you want to execute, and the following options:
- Exit after script: True kills the process after the execution, and False will keep Ansys Speos open.
- Headless: True won’t display the GUI, and False will display it.
- Splash: True will display the startup screen (even if the headless mode is enabled).
- Script Output: Receives as input the filepath to a txt where the python file will all printed text.
- Use Current Directory: This option sets the batch directory as the current directory. When set to True, the command path = os.getcwd() in Python will recognize the batch directory as the path. If it is set to False, the path will be “C:\Program Files\ANSYS Inc\v242\Optical Products\Speos\bin”. This argument enhances automation and simplifies maintenance.
The list of parameters that we can give to Speos launcher is not exhaustive in this section, go to “Configuration Parameters and Command-Line Arguments” section for a more exhaustive list.
To execute the script, you only need to save the .bat and double click on it. If you created a log, you should see a log like it follows:
Process Started...
Importing project...
Project imported.
Finding reflector...
Reflector Status =
Parameters before modifications:
XRadius = 15.0
YRadius = 20.0
Reflector's Status after compute =
Parameters after modifications:
XRadius = 5.0
YRadius = 5.0
Finding Simulation...
Object = Dummy_Simulation [App.Automation.SIM.SimulationDirect]
Simulation Status before compute =
Simulation Status after compute =
Process finished.
Other considerations
- Input Parameters via /ScriptArgs
If you wish to update a parametrization directly via the batch file, you can do so using /ScriptArgs. First, define the parameters in the call to the Speos launcher, as shown below. In this example, XRadius is set to 5 and YRadius is set to 10.
REM Set the root directory to the location of the Speos executable
set root=C:/Program Files/ANSYS Inc/v242/Optical Products/Speos/bin/
REM Set the working directory to the directory of the script
set WORKING_DIR=%~dp0
REM Run the Speos Launcher with the following parameters
"%root%AnsysSpeosLauncher.exe" ^
/RunScript="%WORKING_DIR%Python_with_log.py" ^
/ScriptOutput="%WORKING_DIR%Speos_log.txt" ^
/ScriptArgs="5 10" ^
/ExitAfterScript=True ^
/Headless=True ^
/Splash=True ^
/UseCurrentDirectory=True
Then, you need to modify the python file to receive the parameters using args.
import os
# Variables
path = os.getcwd()
filename = "Start.scdocx"
filepath = os.path.join(path, filename)
try:
print("Process Started...")
# Retrieve parameters from /ScriptArgs
XRadius = float(args[0])
YRadius = float(args[1])
# Print the parameters
print("XRadius : {}".format(XRadius))
print("YRadius : {}".format(YRadius))
# Import project
importOptions = ImportOptions.Create()
print("Importing project...")
DocumentOpen.Execute(filepath, importOptions)
print("Project imported.")
# Update Reflector
print("Finding reflector...")
Reflector = SpeosDes.RectangularSurface.Find("Optical Surface Rectangular.1")
print("Reflector Status = " + str(Reflector.StatusInfo))
print("Parameters before modifications:")
print("XRadius = " + str(Reflector.Groups[0].XRadius))
print("YRadius = " + str(Reflector.Groups[0].YRadius))
Reflector.Groups[0].XRadius = XRadius
Reflector.Groups[0].YRadius = YRadius
Reflector.Compute()
print("Reflector's Status after compute = " + str(Reflector.StatusInfo))
print("Parameters after modifications:")
print("XRadius = " + str(Reflector.Groups[0].XRadius))
print("YRadius = " + str(Reflector.Groups[0].YRadius))
# Update Simulation
print("Finding Simulation...")
dummySimu = SpeosSim.SimulationDirect.Find("Dummy_Simulation")
print("Object = " + str(dummySimu))
print("Simulation Status before compute = " + str(dummySimu.StatusInfo))
dummySimu.Compute()
print("Simulation Status after compute = " + str(dummySimu.StatusInfo))
# Save File
options = ExportOptions.Create()
DocumentSave.Execute(os.path.join(path, "End.scdocx"), options)
except Exception as err:
print("Unexpected error: \n"+str(err)+", "+str(type(err)))
finally:
print("Process finished.")
- Auto-compute features.
One of the limitations of executing the solver in headless is handling the auto-compute features such as TIR Lens or Parabolic Surface. To successfully compute those, you’ll need to force the script execution to stop and re-start. After modifying the feature, you can execute the following:
from SpaceClaim.Api.V242.Scripting.Internal import TransactionHelper
TransactionHelper.EndCommand()
TransactionHelper.BeginCommand("Script")
- Configuration Parameters and Command-Line Arguments
Option | Description |
/DefaultOpenDirectory | Specifies a default file open directory. |
/DefaultSaveDirectory | Specifies a default file save directory. |
/DefaultUserSettingsFile | Specifies the full path of a default user settings file. |
/ExitAfterScript | Specifies if the application should exit when the script (defined by the RunScript options) is finished. |
/Headless | Boolean value indicating whether to run the application in batch mode, without UI. |
/p | Override the Primary SpaceClaim license and Alternate license preferences, and specify a different license on application startup. See License Options for details on the License preference options available. |
Example: | |
SpaceClaim.exe /p=ansys | |
/RunScript | Specifies the fully qualified pathname of the script file to run. |
/ScriptAPI | Specifies the Script API when used with the RunScript option. |
/ScriptArgs | Specifies the script arguments as a comma separated list (for example, ScriptArgs="arg1, arg2, arg3"). |
/ScriptAsync | Boolean value indicating whether to run the script asynchronously. |
/ScriptOutput | Specifies the fully qualified pathname of the script output file. |
/Splash | Boolean value indicating whether to show the splash screen or not. The default value is True. |
/UseCurrentDirectory | Use the current directory as the default file open / save directory. |
/WindowLocation | Sets the window location. For example, /WindowLocation=5,5 |
/WindowMaximized | Sets the window to be maximized, if true. |
/WindowSize | Sets the window size. For example, /WindowSize=1000,800 |