C++ vtknetCDFCFReader reading variables with different dimensions issues - c++

I was trying to read my nc file. There are 3 variables in it, they are:
zonalWind (height, lon, lat)
meridionalWind (height, lon, lat)
verticalVelocity (height_2, lon, lat)
Below is my code reading the arrays:
vtkNetCDFCFReader *reader = vtkNetCDFCFReader::New();
reader->SetFileName(fileName);
reader->SetOutputTypeToStructured();
reader->UpdateMetaData();
reader->Update();
reader->Print(std::cout);
reader->SetVariableArrayStatus("verticalVelocity", 1);
reader->SetVariableArrayStatus("zonalWind", 1);
reader->SetVariableArrayStatus("meridionalWind", 1);
But then I got the following error in termianl skipping the verticalVelocity array because of the dimension problem:
vtkNetCDFCFReader (0x7fb1f1517350): Variable verticalVelocity dimensions (height_2 lat lon) are different than the other variable dimensions (height lat lon). Skipping
Is there any method I can read in all 3 variable data instead of "skipping", and do some processing afterwards?
TIA

No. You should create 2 vtkNetCDFCFReader instances and read variables with the same dimensions for each.
If you want to extract just a portion of the larger grid and use those values on the smaller grid, then attach a vtkExtractGrid filter to one or both of the reader outputs to obtain datasets of the same size. Finally, run a vtkMergeArrays filter on the results to generate a single dataset with all the array values.

Related

Replacing a single row in an R raster

I am looking for the fastest way to assign new values to a whole row of a large raster.
I have a large raster called ras
> ras
class : RasterLayer
dimensions : 71476, 49933, 3569011108 (nrow, ncol, ncell)
resolution : 30, 30 (x, y)
extent : 593235, 2091225, -3314375, -1170095 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=aea +lat_1=-18 +lat_2=-36 +lat_0=0 +lon_0=132 +x_0=0 +y_0=0 +ellps=GRS80 +units=m +no_defs
data source : C:/Users/smithj/AppData/Local/Temp/RtmpiynZ5N/raster/r_tmp_2019-05-04_232648_206436_44436.grd
names : layer
values : 0, 255 (min, max)
And I have a vector of length n=ncol values called newvals. I generate newvals through a function that is not amenable to use with the calc function, but in the example below it is just a randomly generated vector for the purposes of this question.
#create example values
newvals<-sample(0:100,49933, replace=TRUE)
My question is, if I wanted to replace the 7023rd row of ras with newvals is there a faster method than the one below?
#insert newvals into row 7023 of ras
ras[7023,]<-newvals
I have also looked at setValues, but it seems to only set values for a whole raster, not part of it(?). Any help would be appreciated
You do not provide much context. The problem is that you have a large dataset that is file-based, so any change will create a new file (unless you use update).
If you need to do this many times, for example row by row, you can open a new file for writing and write row by row (see writeStart). If it is only one row that needs to be changed, perhaps try your luck with raster::update.

How to use var/variance function in armadillo

How should I be using the var() function in armadillo ?
I have a matrix in which rows are variables/features and columns observations/instances.
I which to get the variance of each row so I can determine variables/features with the greatest variance.
Currently I am calling:
auto variances = arma::var(data, 0, 1);
Where data is my matrix.
As far as I can tell at the moment I am getting a matrix ? And the documentation suggests this is correct. I was expecting to get back a single vector with variance scores for each of my matrix rows.
I can loop through my rows and get the variance for each row individually like so:
for (auto i = 0; i < data.n_rows; ++i)
auto rowVariance = arma::var(dataSet.data.row(i));
But I would prefer not to do this.
I would like to get back a single vector containing variance values for each row in my matrix and then use arma::sort_index() on this vector to get a sorted set of indices corresponding to the sorted variances.
Thanks in advance.
Turns out the error was because I was using arma::var variances = arma::var(data, 0, 1) and should have been using arma::Col<T> variances = arma::var(data, 0, 1)due to my data matrix being of type arma::Mat<T> as I'm allowing both float and double point precision only.
The comment above from vagoberto set me on the right track.

Using xline() with values from a matrix in Stata

I am using xline() to add vertical lines to scatter plots in Stata. I stored the values for the lines, which are the means for different subsamples, in a matrix. Now I want to use the values from the matrix as coordinates in xline().
I tried:
mat means=J(1,5,.)
mat means[1,1]=mean(subsample1)
...
scatter data1 data2, xline(means[1,1])
scatter data3 data4, xline(means[1,2])
...
However, I get the error invalid line argument.
I am grateful for any hint!
// open some example data
sysuse nlsw88, clear
// create a matrix of means
reg grade ibn.race, hascons
matrix means = e(b)
// use those means in -xline()-
scatter wage grade, xline(`=el(means,1,1)' `=el(means,1,2)' `=el(means,1,3)')

How can I turn a three channel Mat into a summed up one channel Mat?

I want to add up all channels of a Mat image to a Mat image with only one sum-channel. I've tried it this way:
// sum up the channels of the image:
// 1 .store initial nr of rows/columns
int initialRows = frameVid1.rows;
int initialCols = frameVid1.cols;
// 2. check if matrix is continous
if (!frameVid1.isContinuous())
{
frameVid1 = frameVid1.clone();
}
// 3. reshape matrix to 3 color vectors
frameVid1 = frameVid1.reshape(3, initialRows*initialCols);
// 4. convert matrix to store bigger values than 255
frameVid1.convertTo(frameVid1, CV_32F);
// 5. sum up the three color vectors
reduce(frameVid1, frameVid1, 1, CV_REDUCE_SUM);
// 6. reshape to initial size
frameVid1 = frameVid1.reshape(1, initialRows);
// 7. convert back to CV_8UC1
frameVid1.convertTo(frameVid1, CV_8U);
But somehow reduce does not touch the color channels as a Matrix Dimension. Is there another function that can sum them up?
Also why does using CV_16U in step 4.) not work? (I had to put a CV_32F in there)
Thanks in advance!
You can sum the RGB channels with a single line
cv::transform(frameVid1, frameVidSum, cv::Matx13f(1,1,1))
You may need one more line, as before applying the transform you shall convert the image to some appropriate type to avoid saturation (I assumed CV_32FC3). -Output array is of the same size and depth as source.
Some explanation:
cv::transform may operate on per-pixel channel values.
Having the third argument cv::Matx13f(a, b, c) for each pixel [u,v] it does the following:
frameVidSum[u,v] = frameVid1[u,v].B * a + frameVid1[u,v].G * b + frameVid1[u,v].R * c
By using third argument cv::Matx13f(1,0,1) you will sum only blue and red channels.
cv::transform is so clever, you can even use cv::Matx14f and then the fourth value will be added (offset) to each pixel in the frameVidSum.
Every 3rd element (in RGB) is one similar colour. Probably it will work if you grab every group of 3 elements (R, G and B) sum them up and store it in another 1-channel matrix. Before storing you should use saturate cast to avoid unexpected results. So, I think the better way is to use saturate cast instead of adapting your matrix.
Have a look at cv::split() and cv::add() functions.
You can use the split function to split the image into separate channels and then the add function to add the images. But be careful when using add because adding may lead to saturation of values. You may have to first convert types and then add. Have a look here: http://answers.opencv.org/question/13769/adding-matrices-without-saturation/

Why? specific pixel processing should be process (h, w) not (w, h) or (x, y)

Some sample code about image processing using OpenCV give somethings like this:
for(i=0;i<height;i++)
{
for(j=0;j<width;j++)
{
if(pointPolygonTest(Point(i,j),myPolygon))
{
// do some processing
}
}
}
In the iteration, why we need to start from height and width? and also why the Point is store (height, width) so that is -> (y,x) ?
Ranges between [0..Height] and [0..Width] are maximum boundaries of your working area.
This code is testing which pixels of whole image are inside the polygon myPolygon.
The word "whole" means you should check all pixels of your image so you should iterate from 0 to height for Y, and iterate from 0 to width for X.
Actually here, the row/column convention is used to iterate over the whole image.
height = Number of Rows
width = Number of Columns
The image is being accessed row wise.The outer loop is iterating over rows of the image and the inner loop is iterating on columns. So basically i is the current row and j is the current column of the image.
The inner loop processes a complete row of the image.