Analysis & Postprocessing

Postprocessing results

92 Topics 258 Posts
  • IMAnalytics Data Preprocessing

    6
    0 Votes
    6 Posts
    454 Views

    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
    250 Views

    i think your simulation is still in process?

  • 2 Votes
    1 Posts
    164 Views
    No one has replied
  • 1 Votes
    3 Posts
    321 Views

    Perfect thanks !!

  • 0 Votes
    6 Posts
    862 Views

    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
  • 0 Votes
    8 Posts
    610 Views

    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
    259 Views

    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.

  • 0 Votes
    4 Posts
    434 Views

    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
    518 Views

    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

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

    2
    1 Votes
    2 Posts
    150 Views

    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
  • Automatic Coil Tuning with the MATCH-Toolbox

    1
    0 Votes
    1 Posts
    121 Views
    No one has replied
  • Optimizer Disabled

    1
    0 Votes
    1 Posts
    119 Views
    No one has replied
  • Half Power Beam Width

    1
    0 Votes
    1 Posts
    121 Views
    No one has replied
  • 0 Votes
    5 Posts
    256 Views

    So definitely max gain it is not useful for my purposes. I wanna construct a more symmetrical radiation pattern and maximize the gain in a certain direction. And of course, I would like to know which parameters I should set up to get such purposes.

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

    1
    0 Votes
    1 Posts
    14 Views
    No one has replied
  • Sincerely ask everyone

    1
    0 Votes
    1 Posts
    145 Views
    No one has replied