Skip to content

Analysis & Postprocessing

Postprocessing results

99 Topics 275 Posts
  • Hyperthermia Optimizer

    2
    0 Votes
    2 Posts
    392 Views
    H

    Hi Vasilis,

    The Hyperthermia Optimizer and Template are licensed products that are not part of the Sim4Life light student version.

    Best,
    Habib

  • scalar product of two vector fields

    2
    0 Votes
    2 Posts
    300 Views
    H

    Hi Gia,

    There is no tool that computes the scalar product for the J-fields from two sensors/simulation. However, you can try to access the fields from Python and compute the product yourself.

    You can extract the J-field in the UI, and then right-click the lowers algorithm in your Analysis tree and select ToPython. This will help you with writing a script to extract certain quantities.

    Best,
    Habib

  • Question about the flux evaluation

    2
    0 Votes
    2 Posts
    248 Views
    SylvainS

    J(x,y,z,f0) is the volume current density:

    081c7de2-7f8f-4450-8e4c-bd69ad8a8ec7-image.png

    So integrating it's flux across a surface, one gets A/m^2 m^2, which simplifies as A. The unit shown in the table viewer unfortunately does not do the simplification...

  • Impedance plotting

    2
    0 Votes
    2 Posts
    326 Views
    ofliO

    Dear @Michael-0

    Please refer to books like Microwave Engineering by Pozar. The impedance matrix is defined as shown in the attached figure (from Pozar) and Z_ii is the input impedance seen looking into port i when all other ports are open-circuited.

    inpedancematrix.png

  • This topic is deleted!

    1
    0 Votes
    1 Posts
    4 Views
    No one has replied
  • "Combining" magnetic and electric model of particles

    1
    0 Votes
    1 Posts
    263 Views
    No one has replied
  • User-Defined Analysis Pipelines

    Unsolved
    1
    0 Votes
    1 Posts
    218 Views
    No one has replied
  • IMAnalytics Data Preprocessing

    6
    0 Votes
    6 Posts
    605 Views
    SylvainS

    hi @mkn,

    I am not sure the indexing will work correctly following your import+renaming workflow. The reason (and that will answer your first question too) is that the indexing is done directly on the 'Output.h5' files and completely ignores the .smash ones. So renaming the simulations in the Sim4Life project may not have the desired effect, unless it also modifies the Output.h5 results.
    The indexing also does not move, modify or otherwise reorganize your collection of Output.h5 files. This has to be done manually, following the folder hierarchy that I described earlier. The indexing itself simply parses the files it finds and builds an index (ending with .sqlite). It is basically at this stage that your output.h5 files acquire some semantic "meaning" (i.e. that they are associated with a given birdcage coil, anatomical model, etc...).

    The "position" is indeed the relative position of the body with respect to the coil. In MRIxViP, the landmark position is defined as the distance between the isocenter of a given bone in the skull of the body and the isocenter of the coil, along the direction of the z-axis of the coil. Note that IMAnalytics will blindly trust that the Output.h5 files it finds in a given folder correspond to the configuration determined by the indexing process (i.e. the labelling of the data is done by placing the files in the correct folders).

  • Analysis

    2
    0 Votes
    2 Posts
    295 Views
    B

    i think your simulation is still in process?

  • How to interpret JsonDataObject data (e.g. from Statistics evaluator)

    1
    2 Votes
    1 Posts
    209 Views
    No one has replied
  • GetComponent(0) how to have both axis in python

    3
    1 Votes
    3 Posts
    450 Views
    L

    Perfect thanks !!

  • Exporting data to Matlab: how to access the data as a volume matrix

    6
    0 Votes
    6 Posts
    1k Views
    L

    Hi,

    Thanks for this answer ! I get it now 🙂

    Best,
    Léa

  • This topic is deleted!

    1
    0 Votes
    1 Posts
    1 Views
    No one has replied
  • Handling Large Field Data Results

    8
    0 Votes
    8 Posts
    870 Views
    M

    Once you have whatever you need as a numpy array I suggest you use one of these functions to visualize it within Sim4Life

    import s4l_v1 as s4l import s4l_v1.document as document import s4l_v1.analysis as analysis import s4l_v1.model as model def visualizeArray(data, x=None,y=None,z=None, unit_name="", unit="", name="", scaling = 1.0, visualize_max = False, scalarrange = None, visualize_isosurface = False, debug = False): """ Create field in postpro to visualize data, if no axis provided then they are automatically assigned based on number of elements in data visualizeArray(data, x=None,y=None,z=None,unit_name="", unit="", name="", scaling = 0.001, goToMax = False) data - numpy array - 3D numpy array x - numpy array - 1D numpy array of x axis coordinates y - numpy array - 1D numpy array of y axis coordinates z - numpy array - 1D numpy array of z axis coordinates unit_name - string - unit name to be displayed unit - string - unit to be displayed name - string - name of field in postpro scaling - float - scaling factor for axes (default 0.001) goToMax - boolean - visualize slice field viewer of maximum in array visualize_slice scalarrange visualize_isosurface isosurface_value debug """ if x is None: x = np.arange(data.shape[0]+1)*.001 if y is None: y = np.arange(data.shape[1]+1)*.001 if z is None: z = np.arange(data.shape[2]+1)*.001 grid = analysis.core.RectilinearGrid() grid.XAxis = np.array(x)*scaling grid.YAxis = np.array(y)*scaling grid.ZAxis = np.array(z)*scaling field = analysis.core.DoubleFieldData() field.Grid = grid if data.size == (len(x) * len(y) * len(z)): field.ValueLocation = analysis.core.eValueLocation.kNode elif data.size == (len(x)-1) * (len(y)-1) * (len(z)-1): field.ValueLocation = analysis.core.eValueLocation.kCellCenter else: print "ERROR: Grid and Data don't match" return False field.NumberOfComponents = 1 field.NumberOfSnapshots = 1 field.Quantity.Unit = s4l.Unit(unit) field.Quantity.Name = unit_name # Note: memory layout is such that x is fastest, z slowest dimension values = data.ravel('F') values = values.astype(np.float64) field.SetField( 0, values ) assert field.Check() producer = analysis.core.TrivialProducer() if name != "": producer.Description = name producer.SetDataObject(field) if visualize_max: sfv = analysis.viewers.SliceFieldViewer() sfv.Inputs[0].Connect( producer.Outputs[0] ) sfv.Slice.Plane = sfv.Slice.Plane.enum.XY sfv.Update(0) sfv.GotoMaxSlice() sfv.Update(0) document.AllAlgorithms.Add(sfv) sfv = analysis.viewers.SliceFieldViewer() sfv.Inputs[0].Connect( producer.Outputs[0] ) sfv.Slice.Plane = sfv.Slice.Plane.enum.YZ sfv.Update(0) sfv.GotoMaxSlice() sfv.Update(0) document.AllAlgorithms.Add(sfv) sfv = analysis.viewers.SliceFieldViewer() sfv.Inputs[0].Connect( producer.Outputs[0] ) sfv.Slice.Plane = sfv.Slice.Plane.enum.XZ sfv.Update(0) sfv.GotoMaxSlice() sfv.Update(0) document.AllAlgorithms.Add(sfv) if visualize_isosurface: iso_surface_viewer = analysis.viewers.IsoSurfaceViewer() iso_surface_viewer.Inputs[0].Connect( producer.Outputs[0] ) iso_surface_viewer.Data.Mode = iso_surface_viewer.Data.Mode.enum.QuantityRealModulus #H CHECK - maybe should just use default (delete this line) iso_surface_viewer.Visualization.ScalarBarVisible = False iso_surface_viewer.UpdateAttributes() iso_surface_viewer.Update(0) document.AllAlgorithms.Add(iso_surface_viewer) document.AllAlgorithms.Add(producer) return producer def visualizeComplexArray(data, x=None,y=None,z=None, unit_name="", unit="", name="", scaling = 1.0, visualize_max = False, scalarrange = None, visualize_isosurface = False, debug = False): """ Create field in postpro to visualize data, if no axis provided then they are automatically assigned based on number of elements in data visualizeArray(data, x=None,y=None,z=None,unit_name="", unit="", name="", scaling = 0.001, goToMax = False) data - numpy array - 3D numpy array x - numpy array - 1D numpy array of x axis coordinates y - numpy array - 1D numpy array of y axis coordinates z - numpy array - 1D numpy array of z axis coordinates unit_name - string - unit name to be displayed unit - string - unit to be displayed name - string - name of field in postpro scaling - float - scaling factor for axes (default 0.001) goToMax - boolean - visualize slice field viewer of maximum in array visualize_slice scalarrange visualize_isosurface isosurface_value debug """ if x is None: x = np.arange(data.shape[0]+1)*.001 if y is None: y = np.arange(data.shape[1]+1)*.001 if z is None: z = np.arange(data.shape[2]+1)*.001 grid = analysis.core.RectilinearGrid() grid.XAxis = np.array(x)*scaling grid.YAxis = np.array(y)*scaling grid.ZAxis = np.array(z)*scaling field = analysis.core.ComplexDoubleFieldData() field.Grid = grid if data.size == (len(x) * len(y) * len(z)): field.ValueLocation = analysis.core.eValueLocation.kNode elif data.size == (len(x)-1) * (len(y)-1) * (len(z)-1): field.ValueLocation = analysis.core.eValueLocation.kCellCenter else: print "ERROR: Grid and Data don't match" return False field.NumberOfComponents = 1 field.NumberOfSnapshots = 1 field.Quantity.Unit = s4l.Unit(unit) field.Quantity.Name = unit_name # Note: memory layout is such that x is fastest, z slowest dimension values = data.ravel('F') #values = values.astype(np.complex64) field.SetField( 0, values ) assert field.Check() producer = analysis.core.TrivialProducer() if name != "": producer.Description = name producer.SetDataObject(field) if visualize_max: sfv = analysis.viewers.SliceFieldViewer() sfv.Inputs[0].Connect( producer.Outputs[0] ) sfv.Slice.Plane = sfv.Slice.Plane.enum.XY sfv.Update(0) sfv.GotoMaxSlice() sfv.Update(0) document.AllAlgorithms.Add(sfv) sfv = analysis.viewers.SliceFieldViewer() sfv.Inputs[0].Connect( producer.Outputs[0] ) sfv.Slice.Plane = sfv.Slice.Plane.enum.YZ sfv.Update(0) sfv.GotoMaxSlice() sfv.Update(0) document.AllAlgorithms.Add(sfv) sfv = analysis.viewers.SliceFieldViewer() sfv.Inputs[0].Connect( producer.Outputs[0] ) sfv.Slice.Plane = sfv.Slice.Plane.enum.XZ sfv.Update(0) sfv.GotoMaxSlice() sfv.Update(0) document.AllAlgorithms.Add(sfv) if visualize_isosurface: iso_surface_viewer = analysis.viewers.IsoSurfaceViewer() iso_surface_viewer.Inputs[0].Connect( producer.Outputs[0] ) iso_surface_viewer.Data.Mode = iso_surface_viewer.Data.Mode.enum.QuantityRealModulus #H CHECK - maybe should just use default (delete this line) iso_surface_viewer.Visualization.ScalarBarVisible = False iso_surface_viewer.UpdateAttributes() iso_surface_viewer.Update(0) document.AllAlgorithms.Add(iso_surface_viewer) document.AllAlgorithms.Add(producer) return producer def visualize2DArray(data, x=None,y=None,z=None, unit_name="", unit="", name="", scaling = 1., visualize_slice = False, scalarrange = None, visualize_isosurface = False, isosurface_value = None, debug = False): """ Create field in postpro to visualize data, if no axis provided then they are automatically assigned based on number of elements in data visualize2DArray(data, x=None,y=None,z=None, unit_name="", unit="", name="", scaling = 0.001, visualize = False, scalarrange = None) data - numpy array - 3D numpy array x - numpy array - 1D numpy array of x axis coordinates y - numpy array - 1D numpy array of y axis coordinates z - numpy array - 1D numpy array of z axis coordinates unit_name - string - unit name to be displayed unit - string - unit to be displayed name - string - name of field in postpro scaling - float - scaling factor for axes (default 0.001) visualize - bool - automatically extract field """ from numpy import newaxis # Deal with dimension of data if data.ndim == 2: data = data[:,:,newaxis] elif data.ndim < 2 or data.ndim > 3: print "Data Dimensions Error" return # Deal with scalar axis by turning into array if np.isscalar(x): x = [x] elif np.isscalar(y): y = [y] elif np.isscalar(z): z = [z] #If axes are not set, then make axes if x is None: x = np.arange(data.shape[0]+1)*.001 if y is None: y = np.arange(data.shape[1]+1)*.001 if z is None: z = np.arange(data.shape[2]+1)*.001 # Deal with monotonically decreasing axes if np.all(np.diff(x) < 0) and np.size(x) > 1: x = x[::-1] data = data[::-1] if debug == True: print "Warning: Monotonically decreasing x axes" if np.all(np.diff(y) < 0) and np.size(y) > 1: y = y[::-1] data = data[:,::-1] if debug == True: print "Warning: Monotonically decreasing y axes" if np.all(np.diff(z) < 0) and np.size(z) > 1: z = z[::-1] data = data[:,:,::-1] if debug == True: print "Warning: Monotonically decreasing z axes" grid = analysis.core.RectilinearGrid() grid.XAxis = np.array(x)*scaling grid.YAxis = np.array(y)*scaling grid.ZAxis = np.array(z)*scaling field = analysis.core.DoubleFieldData() field.Grid = grid if data.size == (len(x) * len(y) * len(z)): field.ValueLocation = analysis.core.eValueLocation.kNode elif data.size == (len(x)-1) * (len(y)-1) * (len(z)-1): field.ValueLocation = analysis.core.eValueLocation.kCellCenter else: print "ERROR: Grid and Data don't match" return field.NumberOfComponents = 1 field.NumberOfSnapshots = 1 field.Quantity.Unit = s4l.Unit(unit) field.Quantity.Name = unit_name # Note: memory layout is such that x is fastest, z slowest dimension values = data.ravel('F') values = values.astype(np.float64) field.SetField( 0, values ) assert field.Check() producer = analysis.core.TrivialProducer() if name != "": producer.Description = name producer.SetDataObject(field) # Adding a SliceSurfaceViewer if visualize_slice: sfv = analysis.viewers.SliceFieldViewer() sfv.Inputs[0].Connect( producer.Outputs[0] ) if len(x) == 1: sfv.Slice.Plane = sfv.Slice.Plane.enum.YZ elif len(y) == 1: sfv.Slice.Plane = sfv.Slice.Plane.enum.XZ elif len(z) == 1: sfv.Slice.Plane = sfv.Slice.Plane.enum.XY sfv.Visualization.ScalarBarVisible = False if scalarrange != None: sfv.ScalarRange = scalarrange sfv.Update(0) document.AllAlgorithms.Add(sfv) # Adding a IsoSurfaceViewer if visualize_isosurface: iso_surface_viewer = analysis.viewers.IsoSurfaceViewer() iso_surface_viewer.Inputs[0].Connect( producer.Outputs[0] ) if isosurface_value is not None: iso_surface_viewer.IsoValues = (isosurface_value,) iso_surface_viewer.Data.Mode = iso_surface_viewer.Data.Mode.enum.QuantityRealModulus #H CHECK - maybe should just use default (delete this line) iso_surface_viewer.Visualization.ScalarBarVisible = False iso_surface_viewer.UpdateAttributes() iso_surface_viewer.Update() if scalarrange != None: iso_surface_viewer.ScalarRange = scalarrange iso_surface_viewer.UpdateAttributes() iso_surface_viewer.Update() document.AllAlgorithms.Add(iso_surface_viewer) document.AllAlgorithms.Add(producer) return producer

    to use it then you would just need to do:

    visualize2DArray(my_data, x_axis, y_axis, z_coordinate)

    and then it should show up in the Postpro / Analysis tab for you to work this

  • 0 Votes
    2 Posts
    306 Views
    S

    Hi,
    Due to end user agreements, you cannot export phantom info in grids.
    According to one of the former entries in this forum, you may consider exporting D and E fields separately and divide them to find epsilon_complex. Similarly, exporting J- and E- fields to calculate conductivity (since J=sigma*E), may help. please be aware that this will not help for the tissue boundaries. You may cross check your computations from the it’is4.0 database loaded in Sim4Life.
    I hope this may help in your situation. Again, please make sure that you are not violating EULA by reconstructing these body models or sharing the data with third parties. Just keep your field results 🙂 not the reconstructed body models.

  • export the data into Matlab... single Tx coil and combined coils for B1

    4
    0 Votes
    4 Posts
    539 Views
    S

    Hi I am not sure if these may help.

    to decrease simulation time (60hrs), you may consider healing the smallest grid. In my simulations, I have time steps usually around 1-3 ps. Anything below 1ps (time step) makes me to revise the model. Modeling cylindrical objects in cartesian coordinates may cause some geometric discrepancies. For example, assume you have a capacitor in one element, which has an only 0.1 mm offset compared to its mirrored counterpart. This means, although you have a capacitor size of a few millimeters, the minimum mesh size would be in the order of 0.05mm! This is terrible for a simulation at 298MHz. To avoid this, I usually model my elements in python environment. Rotating/translating elements manually (without proper snap options) may cause this problem. make sure that all channels have simulation results (I assume multiport simulation) other than that, (These errors may be due to missing simulation result, though) avoid using single port simulations, since you cannot change phases and export results after running a simulation.
  • 0 Votes
    2 Posts
    668 Views
    V

    Hello,

    Sorry but I am thinking of using a time-gate for my own experiment and wondered if you managed to get it working?

    Thanks

  • Combine ports in MATCH for shared matching/tuning network

    1
    0 Votes
    1 Posts
    187 Views
    No one has replied
  • How to switch between linear/log in 2D plot?

    2
    1 Votes
    2 Posts
    215 Views
    G

    For future reference: Okay I just found out that the unit for the y-axis must be set in the "Properties" window of the plot.

  • This topic is deleted!

    1
    0 Votes
    1 Posts
    2 Views
    No one has replied