Paraview create filter with jump in fields - paraview

I have a dataset with discontinuous displacements across a few surfaces (so far I am working in 2D, so these would be lines, 1D).
It is input as a PVDReader (just in case it makes any difference for the question, which I doubt).
Is there any way to programmatically create a new Source with the displacement jumps along those lines?
Note that this new field would probably have to be defined on a domain with a lower dimension, see above.
So far, I created filters PlotOverLine, on lines slightly below and slightly above the prescribed line.
But I do not know how to subtract the two and place them in a single field over the line.
Notes:
So far I am working in 2D (domain where the discontinuity is defined is 1D). I mean to get also discontinuities in fields on 3D domains (domain where the discontinuity is defined is 2D).
As a simple example (see below) I take for Domain of discontinuity: x axis, y=0. I actually mean to have an arbitrary line (in 2D) or plane (in 3D).
I would provide an extra reward if the Domain of discontinuity is an arbitrary curve (in 2D) or surface (in 3D).
Mathematical description:
Discontinuous field: u(x,y)
Domain of discontinuity: x axis, y=0
Value of the field on one side of the domain of discontinuity: u(x+,0)
Value of the field on the other side of the domain of discontinuity: u(x-,0)
Jump in the field: d(x) = u(x+,0) - u(x-,0)
The field u is defined on a 2D domain. The field d is defined on a 1D domain (x axis).

Ressample with dataset should do the trick as far as I understand.
First generate a line using the line source
open your 2D dataset containing the discontinuous U field.
Use ressample with dataset on your dataset and use the line source as source input
You now have a line which contains the field defined on your datasets
If you need to do some computation on it, you can then use a calculator or a programmable filter.

If I understood correctly, you want to plot discontinuity in u(x,y) a 2D surface as a line and associate as a field the jump in u() with d(x) = u(x+,0) - u(x-,0)
Theorically speaking, it should be possible to use a Programmable Filter or develop a ParaView Filter which could take advantage of your filter PlotOverLine and use the lines slightly above and below as its first parameters and use the output line as last parameter (or create it as output).
The different parameters are exposed in the PF script in the array inputs. The question of the order of the parameters can be addressed with a special field 'LineType' for example indicating which is above and which is below.
This way, maybe you could explicitly compute the fields u(x+,0) and u(x-,0) and then the jump field d(x) to finally associate it to the output line.
I'm well aware this is more a suggestion about how it could be done than a real answer but I wanted to share ideas.

I put together a Programmable Filter.
I do not know if this is the most efficient way to do it, but it works.
programmableFilter1 = ProgrammableFilter(Input=[plotOverLineBot,plotOverLineTop])
programmableFilter1.Script = """
import vtk.util.numpy_support as ns
import numpy as np
input_bot = self.GetInputDataObject(0, 0);
input_top = self.GetInputDataObject(0, 1);
output = self.GetPolyDataOutput()
#output.ShallowCopy(input_bot)
npts_bot = input_bot.GetNumberOfPoints()
npts_top = input_top.GetNumberOfPoints()
if ( npts_bot == npts_top ) :
print( "Number of points: " + str(npts_bot) )
u_bot = input_bot.GetPointData().GetArray("displacement")
u_top = input_top.GetPointData().GetArray("displacement")
u_bot_np = ns.vtk_to_numpy(u_bot)
u_top_np = ns.vtk_to_numpy(u_top)
u_jump_np = np.subtract(u_top_np, u_bot_np)
u_jump = ns.numpy_to_vtk(u_jump_np)
u_jump.SetName("displacement jump");
output.GetPointData().AddArray(u_jump)
else :
pass
"""
programmableFilter1.RequestInformationScript = ''
programmableFilter1.RequestUpdateExtentScript = ''
programmableFilter1.PythonPath = ''
RenameSource("Programmable Filter - Jumps", programmableFilter1)

Related

Equivalent for (:) for slices of higher dimension matrices

Context
You have a 3D variable A
rng('default')
A = randi(100,5,7,3);
Problem
You want to get a column vector with all the values of a given slice along the third dimension of A, e.g.
Tmp = A(:,:,2);
out = Tmp(:);
Question
Is there a built in way to do this directly without having to use a temporary variable or a function (i.e. with a combination of brackets, ...)? The closest to what I look for I have found yet would be
out = reshape(A(:,:,2),[],1)
Which I find a bit "heavy". I was looking for something like (A(:,:,2))(:) but it doesn't work in MATLAB.
The fact that they added the input all in functions like any would suggest that there is not but I figured I'd still ask

How to handle flag/exception values

In Paraview, I am working with a dataset that uses the value -99999 as a flag value. I'd like to be able to manipulate the dataset without these values causing issues with things like glyphs and colorbars. Nominally, I'd like the data to be "ignored".
A little about the data: I've got both scalar and vector point data, sitting on a fixed 2D spatial mesh at set temporal intervals.
Although -99999 is very far beyond the values the data might otherwise show, using a threshold filter isn't an option because the flag can occur at different places at different times. The way Paraview's threshold filter works means that the point ID to a fixed point in space will change as the number of filtered points changes through time.
In case it matters, data are in a netCDF file that is read in via an XMF header file and the XDMF Reader since the CF reader doesn't work (possibly because of my unstructured triangular mesh). The netCDF data have the _FillValue global attribute, however this doesn't appear to be getting picked up on by Paraview.
You could use a Programmable Filter to replace values below -99999 by NaN. Providing the data is not a vtkMultiblockDataSet, you can use the following script in the programmable filter :
import numpy as np
from vtk.numpy_interface import dataset_adapter as dsa
# name of the array
name = 'name'
# limit
limit = -99999
array = inputs[0].PointData[name].copy()
array[array<=limit] = np.nan
out = dsa.WrapDataObject(self.GetOutput())
out.PointData.append(array, name)
Note: if data of interest is a Cell Data, replace PointData by CellData in the script.
Note 2: the script was tested on ParaView 5.6.

How to use binning method for identifying the incoming point belongs to which bin?

I have small query. I have two data sets. In one data sets for example I did binning and calculated the mean value and std value along with group binning. Now in I have second data sets of same parameters say X. I would like identify this X data sets belong to which bin groups of my previous data sets using matlab.
Could you give some example how to identify the incoming data points belongs to which bin group...??
I used following binning which is available in matlab :
binEdges = linspace(botEdge, topEdge, numBins+1);
[h,whichBin] = histc(x, binEdges);
Well... you already have your bin edges. Anything inside specific edges is in that bin.
If you know that the data is inside the ranges you defined then, for each new data
newdatabin=find(newdata>binedges,1,'last'); %this is the bin number where the new data goes in
h(newdatabin)=h(newdatabin)+1; %add one!
Also consider using histcounts if your MATLAB version is new enough.

3-D Vector Fields for Modeling

I hope this isn't too general of a question, but I'm having an issue with some syntax in this 3D vector field example provided on Mathworks' website in addition to actually just understanding how to make the 3d vector fields.
I'm trying to create a very robust 3D vector field to model wind patterns based on current NOAA information for a geographic region to predict (or simulate) a path in which a balloon system / parachute system would / should drift on ascent and descent.
In saying that, I'm just starting with the 3D vector fields and the same could be said for 2D vector fields, but I can't seem to find a great resource for the 3D ones.
field := plot::VectorField3d([1, sin(x) + cos(y), sin(z)],
x = 0..6, y = 0..2.5, z = 0..5,
Mesh = [7, 7, 7]):
plot(field):
This is one of the examples, but I'm not familiar with the usage of ".." in succession or the stacking that they seem to have done with the lines. I've tried copying this into a new ".m" file that I created and running it, but I get: "Unexpected MATLAB expression". I've tried guessing at the notation by switching ".." to ":" and the ending ":" to a ";" , but I didn't get anywhere.
If you need me to clarify, let me know, and thanks for reading / helping in advance!
0..6 stands for a range - see http://www.mathworks.com/help/symbolic/mupad_ref/uname.html
To run your example, type mupad in the command window and paste the example in the mupad editor.

Get specific label (incl. data) of k-means

first of all, I'd like to describe my issue with the kmeans in Matlab.
I select a point via mouse and use it for cluster initialization. This works fine.
After the segmentation of the data, I reshape the data back into proper style, because I need a matrix.
Now I want to select only the cluster of which the user selected the data via mouse.
Therefore I select the index of the mouse-coordinates to select the label, which I want to segmentate. Because of other extra data which is not connected or nearby the relevant data, but also gots the same label.
I want to select only connected-components in a neighbourhood of 8.
So here is my code snippet so far:
flatimg = double(reshape(croppedimg,size(croppedimg,1)*size(croppedimg,2),size(croppedimg,3)));
% kmeans
[idx, clusters] = kmeans(flatimg,2,'start',[seedpoint1(3);seedpoint2(3)]);
% form it back to a matrix
k=reshape(idx,size(croppedimg,1),size(croppedimg,2));
%convert point, which is part of the label I want to linear index
selectedobjectpoint = sub2ind(size(croppedimg),seedpoint1(2),seedpoint1(1));
hgplabel = k(selectedobjectpoint);
idx_object = find(k, hgplabel);
% also tried: idx_object = find(k == hgplabel);
I added a screenshot, which shows the direct output of kmeans:
So my aim is it here to get only the "white" OR the "black" ones.
Help or advice appreciated. If you've got any questions regarding the snippet or the goal, feel free to ask.
Thank you in advance!
I think the FIND command is throwing you off. You want something like:
logicalImage = k == hgplabel;
bwImg = bwlabel(logicalImage);
imagesc(bwImg)
FIND will output the indices where k == hgplabel. You want the matrix of zeros and ones where k takes that value (I think).
If you just want the connected components of that, the output of bwlabel will contain unique integers for each connected component, so imagesc(bwImg == 1) will show just component 1. And you can specify the connectivity