Skip to content

Python API

Scripting interface for Sim4Life

127 Topics 375 Posts
  • Extract the bounding box of a solid

    Pinned
    2
    0 Votes
    2 Posts
    792 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
    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
    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.

  • Algorithm "Max Modulation" was not yet exposed in the Python API

    19
    0 Votes
    19 Posts
    429 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
    39 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
    80 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
    91 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
    192 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
    83 Views
    No one has replied
  • Is it possible to use Python API without opening Sim4Life?

    4
    0 Votes
    4 Posts
    593 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
    77 Views
    No one has replied
  • About TI Simulation

    4
    0 Votes
    4 Posts
    204 Views
    L

    I want to see the impact of different grid sizes on the simulation, so I cloned a pair of simulations and modified the maximum step size of the grid. However, I found that if I create a new pair of simulations using the same settings, the grid sizes, simulation durations, and results of the new simulations and the cloned simulations are all different. Why does this happen?

  • Iso Surfaces - Creating volumes with a threshold

    1
    0 Votes
    1 Posts
    88 Views
    No one has replied
  • Accessing specific entities of my model from the python API

    2
    1 Votes
    2 Posts
    126 Views
    L

    found my own answer:

    image.png

  • Installing Additional Python Packages in Sim4Life Environment

    Solved
    9
    1 Votes
    9 Posts
    435 Views
    G

    @Sylvain Yes thanks finally I succeed!

  • 1 Votes
    1 Posts
    94 Views
    No one has replied
  • Clear or Reset Geometry Workspace in Python?

    4
    0 Votes
    4 Posts
    534 Views
    brynB

    I typically do the following (which also clears the history and frees memory):

    import XCoreModeling as xcm xcm.GetActiveModel().Clear()
  • RuntimeError: Could not allocate memory for numpy array

    3
    0 Votes
    3 Posts
    1k Views
    SylvainS

    have you tried overwriting the E_field and raw_data variables?

  • Extract the EM E field along the Spline

    3
    0 Votes
    3 Posts
    385 Views
    A

    Thank you so much for hour help with the technical issue!
    Your assistance made a big difference, and I truly appreciate your expertise and prompt support!

  • Max modulation tool in API

    2
    0 Votes
    2 Posts
    454 Views
    J

    Would like to know too in 2024 🙂