Python API

Scripting interface for Sim4Life

113 Topics 314 Posts
  • Extract the bounding box of a solid

    Pinned
    2
    0 Votes
    2 Posts
    552 Views

    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)
  • 2 Votes
    3 Posts
    780 Views

    @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.

  • 0 Votes
    3 Posts
    931 Views

    "Experimental" in that context means that the API may change in the future and that backward compatibility may break.

  • 0 Votes
    2 Posts
    84 Views

    short answer: you can run most of the Python API without opening the Sim4Life user interface.

    you have different options

    you can call Sim4Life.exe --run your_script.py you can write scripts and run them using the python.exe in the Sim4Life installation you can create a virtual environment with the Sim4Life packages, e.g. "C:\Program Files\Sim4Life_6.2.2.6592\Python\python.exe" -m venv .venv --system-site-packages and then use the python from this venv to run your script

    The first option opens Sim4Life, runs the script, and closes Sim4Life again. It probably is the easiest option to work robustly.

    The latter two options run without the UI and by default without an application. In most cases, you will need an application though (e.g. the Application initializes the active model, which is needed for modeling). For Python scripting without the UI you can create a console application. We do this e.g., to run Python tests without opening the UI (which is slower). To create a console application you can usually call:

    import XCore XCore.GetOrCreateConsoleApp() # now you can do some stuff import s4l_v1 as s4l sphere = s4l.model.CreateSolidSphere(s4l.model.Vec3(0.0), 1.0)
  • Change parameters in Simulation Combiner

    2
    0 Votes
    2 Posts
    129 Views

    The following example for a 2-port simulation combiner should help.

    i = 0 for channel in em_multi_port_simulation_combiner.GetChannelWeights(): power = [1.0, 2.0] phase = [45, 90] em_multi_port_simulation_combiner.SetChannelWeight(channel, power[i], phase[i]) i += 1 em_multi_port_simulation_combiner.UpdateAttributes() em_multi_port_simulation_combiner.Update() document.AllAlgorithms.Add(em_multi_port_simulation_combiner)
  • Geometry Modeling - Snapping to Endpoints in Python API ?

    Unsolved
    3
    0 Votes
    3 Posts
    167 Views

    Hi @dbsim4
    I think it would help a lot if you could post an image depicting what you are trying to achieve.

    Answering the question from the subject line: No, there is no snapping in Python (not sure how that API could look like), but there are functions to get the distance between entities (and corresponding closest points), which may help.

    brick1 = XCoreModeling.CreateSolidBlock(Vec3(0), Vec3(1)) brick2 = XCoreModeling.CreateSolidBlock(Vec3(2), Vec3(3)) res = XCoreModeling.GetEntityEntityDistance(brick1, brick2) print(f"Distance brick1-brick2: {res[0].Distance}") print(f"Closest point on brick1: {res[0].ClosestPosition}") print(f"Closest point on brick2: {res[1].ClosestPosition}")

    or distance to a point:

    brick = XCoreModeling.CreateSolidBlock(Vec3(0), Vec3(1)) res = XCoreModeling.GetEntityEntityDistance(brick, Vec3(3)) print(f"Distance brick-point: {res.Distance}") print(f"Closest point on brick: {res.ClosestPosition}")

    For geometry that has end-points or corners, you could extract the vertices and again use distance wrt some other point as a way to write a script.

    edge = XCoreModeling.CreateEdge(Vec3(0), Vec3(1)) vertices = XCoreModeling.GetVertices(edge) assert len(vertices) == 2 for v in vertices: print(v.Position) brick = XCoreModeling.CreateSolidBlock(Vec3(0), Vec3(1)) vertices = XCoreModeling.GetVertices(edge) assert len(vertices) == 8
  • How to create solid circle ie. with surface ?

    Unsolved
    4
    0 Votes
    4 Posts
    150 Views

    @dbsim4 regarding your "Update", I am not sure I understand the context. Are you trying to assign the circle loop as an edge source?

  • Refresh Matlab Expoter

    2
    0 Votes
    2 Posts
    162 Views

    Like all entities in the Analysis pipeline, the Matlab exporter has an Update method to execute.

    to find more information on a specific class you can

    export the pipeline from the GUI as a python script use the help() function to get more information on a specific class, e.g. import s4l_v1 as s4l help(s4l.analysis.exporters.MatlabExporter)
  • Interaction with Neuron results

    2
    0 Votes
    2 Posts
    197 Views

    @Hüfer yes, you can access all the simulation results as well as the parameters of you EM-neuronal simulations using the Python interface. For example, you can access titration data, or the transmembrane voltage profiles stored on a point or line sensor data, etc. or you can dynamically change the stimulation pulse shape parameters (phase duration, amplitude, etc.).

    Sim4Life provides you already with some Python tutorials. There are at least 3 tutorials provided that show how to use Python to setup a T-Neuron simulation, how to run it and how to access the simulation results. Please have a look at these tutorials to learn Sim4Life programming (if you are a Python expert, learning will take you a day!).

    To access these tutorials, open the 'Scripter' panel in Sim4Life, and load one of the scripts in the folder opened when selecting "Open Example Script" clicking on the open folder button.

  • multiport sensor combiner freq normalization

    1
    0 Votes
    1 Posts
    118 Views
    No one has replied
  • This topic is deleted!

    1
    0 Votes
    1 Posts
    1 Views
    No one has replied
  • clear simulation

    2
    0 Votes
    2 Posts
    190 Views

    Hi Michael,

    What type of simulation/solver you are running?

    If I understand correct, all the simulations are of the same size, but the output files are of different sizes? This should not be the case.

    Unless simulations have larger grids, more sensors recorded, more frequency snapshots, etc, the output file size must not change.

    Best,
    Habib

  • Specifying diameter during axon discretization

    2
    0 Votes
    2 Posts
    157 Views

    I have managed to solve this. The function below seems to work

    def DiscretizeAxonModel(Axon_name, Diameter, type,folder): axon_entity = model.AllEntities()[Axon_name] if type=='motor': model_properties=model.MotorMrgNeuronProperties() elif type=='sensory': model_properties=model.SensoryMrgNeuronProperties() else: model_properties=model.MotorNeuronProperties() model_properties.AxonDiameter=Diameter discretized_axon = model.CreateAxonNeuron(axon_entity,model_properties) discretized_axon.Name = Axon_name +'_neuron' folder.Add(discretized_axon)
  • This topic is deleted!

    1
    0 Votes
    1 Posts
    12 Views
    No one has replied
  • This topic is deleted!

    1
    0 Votes
    1 Posts
    8 Views
    No one has replied
  • read output files

    3
    0 Votes
    3 Posts
    307 Views

    solved with h5py read :
    import h5py

    with h5py.File(fname,'r') as hdf:
    FieldGroups=hdf['FieldGroups']
    keygroup = list(FieldGroups.keys())
    valField = FieldGroups[keygroup[0]]
    AllFields = valField['AllFields']
    EMPotential = AllFields['EM Potential(x,y,z,f0)']
    EMPotentialObject = EMPotential['_Object']
    AdditionalFieldDataCollection =
    EMPotentialObject['AdditionalFieldDataCollection']
    Snapshots = EMPotentialObject['Snapshots']
    Potential = Snapshots['0']['comp0']

    #(n, m, k, 2) numpy array PotentialData = Potential[()]

    ==========
    this can be plotted
    import pyvista as pv

  • How to export voxel data using python API?

    3
    0 Votes
    3 Posts
    403 Views

    @montanaro I've tried it and it worked. Thank you very much!

  • one document with many simulations

    5
    0 Votes
    5 Posts
    316 Views

    can you supply some code example ? thanks

  • Masking entities in python

    6
    0 Votes
    6 Posts
    460 Views

    @Spuky sorry, I guess the legacy code was confusing:

    masking_filter = s4l.analysis.core.FieldMaskingFilter() masking_filter.SetInputConnection(0, J_port)

    I edited the original answer to use the current API. The J_port was the output port for the J(x,y,z,f0) field.

  • Deleting Entities by Name

    3
    0 Votes
    3 Posts
    263 Views

    @AntoninoMC thanks, that worked perfect!