Skip to content

Analysis & Postprocessing

Postprocessing results

105 Topics 302 Posts
  • Padding field with constant value

    1
    0 Votes
    1 Posts
    196 Views
    No one has replied
  • Import modulation file

    10
    0 Votes
    10 Posts
    866 Views
    M

    Really sorry, I honestly don't understand - I don't know what you mean with modulation and I'm not sure what you mean with using matlab and what input file you are exactly referring to. Maybe some screenshots will help, otherwise maybe contact support

  • Magnetic induction power analysis

    1
    0 Votes
    1 Posts
    215 Views
    No one has replied
  • Thermal

    1
    0 Votes
    1 Posts
    201 Views
    No one has replied
  • Time Domain

    2
    0 Votes
    2 Posts
    346 Views
    ofliO

    Hi,

    Currently, there is no tool in Sim4Life allowing you to extract the S-parameter in time domain. You might evaluate it via Python scripting (using already available time-domain data of voltage and current at ports or inverse Fourier Transform). Sim4Life team is informed to include this request in the development plan and will inform you in the future once it is implemented.

  • P-EM-QS sweeps - can't view results for magneto quasi-static

    2
    0 Votes
    2 Posts
    434 Views
    S

    I've solved the issue. The sweep works if I set the source for the QS solver to a coil (wire current settings) instead of linking in that data from the SV solver (vector potential settings).

  • Hyperthermia Optimizer

    2
    0 Votes
    2 Posts
    449 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
    324 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
    283 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
    357 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
    288 Views
    No one has replied
  • User-Defined Analysis Pipelines

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

    6
    0 Votes
    6 Posts
    675 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
    316 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
    242 Views
    No one has replied
  • GetComponent(0) how to have both axis in python

    3
    1 Votes
    3 Posts
    521 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
    1k 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