Skip to content

Python API

Scripting interface for Sim4Life

136 Topics 424 Posts
  • Extract the bounding box of a solid

    Pinned
    2
    0 Votes
    2 Posts
    1k Views
    SylvainS
    There is a function that returns the bounding box of an entity. Let us assume you have an entity called 'object 1'. The following code should return the coordinate vectors of two diagonally opposite corners of the bounding box: import s4l_v1.model as model import XCoreModeling entity = model.AllEntities()['object 1'] bb_lower, bb_upper = XCoreModeling.GetBoundingBox([entity]) You can then use the model.CreateWireBlock() function to create an object which you can use in your simulation settings. For more detail: help(XCoreModeling.GetBoundingBox) help(model.CreateWireBlock)
  • Moving from SEMCAD 14.8 to Sim4Life python API

    Pinned python semcad
    3
    2 Votes
    3 Posts
    1k Views
    pcrespoP
    @pcrespo said in Moving from SEMCAD 14.8 to Sim4Life python API: How can we synchronize the entities in a model with a simulation (say, s4l_v1.simulation.emfdtd.Simulation)? Previously, the SolidRegions in a simulation seemed to be synchronized with model entities automatically, but it seems that SolidRegions are not available in simulations anymore. Yes, the philosophy there changed a bit. The idea is that every context adds a new layer of information on top of the previous one. When the user starts modeling, it is expected to define the geometry of the problem. For instance, what is the shape, position and size of a given entity. The simulation context adds the necessary information to the geometry of the problem so that we can perform a numerical simulation. These new settings could be related with the physics of the problem (e.g. electric properties of a given geometry ) or with the numerical method (e.g. fdtd grid details for the discretization of a given geometry). Creating a simulation in the UI reveals what type of settings each simulation type adds on the associated modeling entities. Another big different with respect to SEMCAD is that every simulation uses a selection of entities instead of using by default all and having to unselect/ignore them. It has the same result but the producer is reversed. Then, coming back to the API, assume we want to simulate a dipole antenna.. To start I modeled two arms and a line to define the feed. I can retrieve them by name as follows: import s4l_v1.model as model entities = model.AllEntities() arm1 = entities['Arm 1'] arm2 = entities['Arm 2'] line = entities['SourceLine'] Now i want to create a simulation that uses this geometry. In order to assign a material to these entities, I need to a) associate the entities to the simulation (they become simulation components) b) create material settings and c) assign these settings to the associated entities. The API provides a shortcut for these three operations simulation.Add*Settings . This directly returns the settings object assigned to the entity within this simulation. Then we can set the values of the different properties: simulation = fdtd.Simulation() # ... some general settings ... # Materials: dipole_material = simulation.AddMaterialSettings([arm1, arm2]) dipole_material.Name = 'Dipole Arms' dipole_material.MaterialType = dipole_material.MaterialType.enum.PEC and analogously with the line entity: edgesrc_settings = sim.AddEdgeSourceSettings([line,]) options = edgesrc_settings.ExcitationType.enum edgesrc_settings.ExcitationType = options.Gaussian edgesrc_settings.CenterFrequency = 300., units.MHz edgesrc_settings.Bandwidth = 300., units.MHz The model entity in a simulation and with all the extra layers is now referred as a simulation component. In other words, a simulation component is a geometry (defined by model entity) with several layers of settings corresponding to the physics and the numerical methods.
  • API Documentation - searching for functions

    Pinned python documentation api browser
    3
    1 Votes
    3 Posts
    2k Views
    SylvainS
    "Experimental" in that context means that the API may change in the future and that backward compatibility may break.
  • Inquiry Regarding TI Simulation Setup in Sim4Life

    1
    0 Votes
    1 Posts
    14 Views
    No one has replied
  • 0 Votes
    4 Posts
    292 Views
    brynB
    thanks for this feedback. we will try to add more examples that demonstrate how to use/modify anatomical models, triangle meshes, etc.
  • Extraction of Tissue Properties Along a Spline

    1
    0 Votes
    1 Posts
    76 Views
    No one has replied
  • Error in TI tutorial

    16
    0 Votes
    16 Posts
    2k Views
    A
    Thank you for your help. I will run it in a previous version.
  • Importing STL as Solid body

    6
    1 Votes
    6 Posts
    664 Views
    brynB
    I tried to reproduce this doing the following. I create three entities a cylinder copy it and convert the copy to a triangle mesh generate an unstructured tetrahedral mesh Then I drag these entities to the Analysis (ModelToGridFilter in Python API). I tried to use the surface viewer, but since they have no fields, nothing is displayed (this changed since 7.0 or before - it used to display a white surface). To generate a field I used the Calculator, and added expressions like coordsY*jHat, i.e. (0, coordsY, 0) where coordsY is the y-coordinate from the points in the geometry. Create a vector viewer for each (from the left: Solid Body, TriangleMesh, UnstructuredMesh). The third one samples vector values using Line/Plane/Box sources. [image: 1749109986009-d5bc2f0e-af54-4fca-8265-1431e94207ca-image.png] To get the vectors on the surface of the UnstructuredMesh, I had to first extract the surface, via Field Data Tools -> Surface Filter [image: 1749110185730-938040d9-2fcf-4cad-a42e-7c2f0d4592ec-image.png] The generated Python ("To Python' in context menu) script for item 5 was: # This script was auto-generated by Sim4Life version 8.2.0.16890 import numpy import s4l_v1.analysis as analysis import s4l_v1.document as document import s4l_v1.model as model import s4l_v1.units as units from s4l_v1 import ReleaseVersion from s4l_v1 import Unit try: # Define the version to use for default values ReleaseVersion.set_active(ReleaseVersion.version8_2) # Creating the analysis pipeline # Adding a new ModelToGridFilter inputs = [] model_to_grid_filter = analysis.core.ModelToGridFilter(inputs=inputs) model_to_grid_filter.Name = "Cylinder 3" model_to_grid_filter.Entity = model.AllEntities()["Cylinder 3"] model_to_grid_filter.UpdateAttributes() document.AllAlgorithms.Add(model_to_grid_filter) # Adding a new FieldCalculator inputs = [model_to_grid_filter.Outputs["Unstructured Grid"]] field_calculator = analysis.field.FieldCalculator(inputs=inputs) field_calculator.Expression = u"coordsZ*kHat" field_calculator.UpdateAttributes() document.AllAlgorithms.Add(field_calculator) # Adding a new FieldSurfaceFilter inputs = [field_calculator.Outputs["Result(x,y,z)"]] field_surface_filter = analysis.field.FieldSurfaceFilter(inputs=inputs) field_surface_filter.UpdateAttributes() document.AllAlgorithms.Add(field_surface_filter) # Adding a new VectorFieldViewer inputs = [field_surface_filter.Outputs["Result(x,y,z)"]] vector_field_viewer = analysis.viewers.VectorFieldViewer(inputs=inputs) vector_field_viewer.Data.Phase = u"0°" vector_field_viewer.Vector.Plane.PlaneCenter = numpy.array([0.05300000309944153, -0.03099999949336052, 0.012000000104308128]) vector_field_viewer.UpdateAttributes() document.AllAlgorithms.Add(vector_field_viewer) except Exception as exc: import traceback traceback.print_exc() # Reset active version to default ReleaseVersion.reset() raise(exc)
  • Python scripting padding settings

    5
    0 Votes
    5 Posts
    544 Views
    T
    This is in an older version of sim4life 8.0, maybe the problem has already been fixed. Otherwise I think this was a multiport simulation but I forget now... Maybe that could be a strange bug where it works for multi but not single or vise versa.
  • 0 Votes
    5 Posts
    648 Views
    M
    So my problem was solved for the simple phantom a sphere. It can be voxeled. I am having a discussion with chatgpt about how to load Duke into the simulation section because currently it wont be voxeled. Is there a simple few lines of code that loads Duke and all the default tissue electrical properties or is it necessary to assign each tissue type in a loop or via thousands lines of code (as I have seen elsewhere)....
  • 0 Votes
    9 Posts
    1k Views
    L
    @Sylvain I exported the electric field results from an AC simulation and found that the last six columns of the data are imaginary numbers. Are these the electric field values in three different directions? Why aren't they time-varying? Did I only export the peak values?
  • AttributeError: 'NoneType' object has no attribute 'Results'

    2
    0 Votes
    2 Posts
    335 Views
    SylvainS
    Hi, You would get that error if there was no simulation named "0_17_35_29" in the currently opened document. Maybe you should check what simulations you have in your project and if you do have a simulation with that name? One way to list all simulation names via python is to run something like: for s in document.AllSimulations: print(s.Name)
  • Algorithm "Max Modulation" was not yet exposed in the Python API

    19
    0 Votes
    19 Posts
    2k Views
    L
    @halder When I performed TI simulation using the spherical model, I found that if I changed the current direction of one pair of electrodes, the maximum value of the TI Max (x, y, z) slice remained unchanged. Changing the current of one pair of electrodes should have shifted from the original same-direction superposition to a reverse weakening, so why does it remain unchanged? Is it because Max Modulation only uses EM for calculations?
  • Access data directly

    2
    0 Votes
    2 Posts
    310 Views
    H
    Hi, you can try something like the following to extract the reflection coefficient. You can always try to build extraction manually once and select "To python" by right-clicking on the end of the tree (i.e. the component you extract from your pipeline) import numpy import s4l_v1.analysis as analysis import s4l_v1.document as document import s4l_v1.model as model import s4l_v1.units as units from s4l_v1 import ReleaseVersion from s4l_v1 import Unit sim_name = "MRI Volume Coil Cleg = 29.5 pF" ###### define the sim name in this case this is a multiport FDTD simulation Adding a new EmMultiPortSimulationExtractor simulation = document.AllSimulations[sim_name] em_multi_port_simulation_extractor = simulation.Results() this is extracting a port inputs = [em_multi_port_simulation_extractor.Outputs["MRI Volume Coil Cleg = 29.5 pF - Endring source 1 (Birdcage 1)"]] em_port_simulation_extractor = analysis.extractors.EmPortSimulationExtractor(inputs=inputs) em_port_simulation_extractor.Name = "MRI Volume Coil Cleg = 29.5 pF - Endring source 1 (Birdcage 1)" em_port_simulation_extractor.UpdateAttributes() document.AllAlgorithms.Add(em_port_simulation_extractor) em_sensor_extractor = em_port_simulation_extractor["Endring source 1 (Birdcage 1)"] document.AllAlgorithms.Add(em_sensor_extractor) ref_coef_data = em_sensor_extractor.Outputs["Reflection Coefficient(f)"] ref_coef_data.Update() freqlist = ref_coef_data.Data.Axis ref_coef = refCoeff.Data.GetComponent(0) ref_coef_magnitude = np.sqrt(np.real(ref_coef)**2 + np.imag(ref_coef)**2) import matplotlib.pyplot as plt plt.plot(freqlist,ref_coef_magnitude)
  • How to suppress messages in the Python console?

    2
    0 Votes
    2 Posts
    337 Views
    L
    As far as I'm aware it is not possible to suppress those messages. Maybe try writing your customized messages into a log file instead?
  • How to create voxels using a script?

    2
    0 Votes
    2 Posts
    347 Views
    L
    Hi! In all the tutorial python scripts this is shown. Within the python scripter you can click on the folder icon and choose "Open Example Script". There you will find lots of python scripts, that show how this is done. Here a small excerpt from the script "tutorial_emlf_parallel_plate.py": sim = CreateSimulation() s4l_v1.document.AllSimulations.Add(sim) sim.UpdateGrid() sim.CreateVoxels(path) sim.RunSimulation(wait=True) I suggest always creating a simulation, and an analysis function, that is then called in the RunTutorial function. It's best to then also create a main: def RunTutorial( path ): import s4l_v1.document s4l_v1.document.New() CreateModel() sim = CreateSimulation() s4l_v1.document.AllSimulations.Add(sim) sim.UpdateGrid() sim.CreateVoxels(path) sim.RunSimulation(wait=True) AnalyzeSimulation(sim) def main(data_path=None, project_dir=None): """ data_path = path to a folder that contains data for this simulation (e.g. model files) project_dir = path to a folder where this project and its results will be saved """ import sys import os print("Python ", sys.version) print("Running in ", os.getcwd(), "@", os.environ['COMPUTERNAME']) if project_dir is None: project_dir = os.path.expanduser(os.path.join('~', 'Documents', 's4l_python_tutorials') ) if not os.path.exists(project_dir): os.makedirs(project_dir) fname = os.path.splitext(os.path.basename(_CFILE))[0] + '.smash' project_path = os.path.join(project_dir, fname) RunTutorial( project_path ) if __name__ == '__main__': main()
  • import element inside a group using python

    5
    0 Votes
    5 Posts
    722 Views
    M
    Thank you, I could obtain the same also using this: analysis.exporters.MatlabExporter.ExportTo(matlab_exporter,matlab_exporter.FileName) Do you think it is a good solution as well?
  • python script to run in the cloud

    1
    0 Votes
    1 Posts
    207 Views
    No one has replied
  • Is it possible to use Python API without opening Sim4Life?

    4
    0 Votes
    4 Posts
    1k Views
    brynB
    You can open a smash file using import s4l_v1 as s4l s4l.document.Open(smash_file_path) You can save it using s4l.document.Save(smash_file_path) You can find a simulation using (assuming you have unique simulation names sim = [sim for sim in s4l.document.AllSimulations if sim.Name == "the name of your simulation"][0] If you want to load different models (from .sab file or .smash), but don't need to load e.g. simulations (in .smash file), you can import the file entities = s4l.model.Import(file_path) if you need to reset the document or model because you are accumulating too many entities and memory use is getting too high, you can use e.g. # reset the model sl4.model.Clear() # or keep entities, but discard model history import XCoreModeling as xcm xcm.GetActiveModel().ClearHistory() # or reset entire document (reset model, simulations, analysis) s4l.document.New()
  • Location of Simulation Outputs and Voxel Coordinates?

    1
    0 Votes
    1 Posts
    197 Views
    No one has replied