How to concatenate two netcdf files with 3 time variables - netcdf

I have two NetCDF files that I need to concatenate. Both files have exactly the same variables and there are 3 time variables, time0, time1, time2 and time2 is the record variable
Using the NCO tools, when I try the command:
ncrcat ${input1} ${input2} -o ${output}.
it only concatenates the variables which are dependent on the record variable time2.
What do I need to do to concatenate the variables that are dependent on the other two time variables?
Added headers for clarification:
netcdf tn_2018061706-utc_nzcsm_bap1 {
dimensions:
time2 = UNLIMITED ; // (48 currently)
rlat = 971 ;
rlon = 741 ;
bnds = 2 ;
bnds_4 = 4 ;
time0 = 49 ;
time1 = 48 ;
variables:
float sum_total_precip(time2, rlat, rlon) ;
sum_total_precip:cell_methods = "time2: sum" ;
sum_total_precip:coordinates = "latitude longitude" ;
sum_total_precip:grid_mapping = "rotated_latitude_longitude" ;
sum_total_precip:long_name = "sum of rain and lwe snowfall amounts" ;
sum_total_precip:standard_name = "precipitation_amount" ;
sum_total_precip:units = "kg m-2" ;
int rotated_latitude_longitude ;
rotated_latitude_longitude:grid_mapping_name = "rotated_latitude_longitude" ;
rotated_latitude_longitude:grid_north_pole_latitude = 49.5499992370605 ;
rotated_latitude_longitude:grid_north_pole_longitude = 171.770004272461 ;
rotated_latitude_longitude:north_pole_grid_longitude = 0. ;
float time2(time2) ;
time2:axis = "T" ;
time2:bounds = "time2_bnds" ;
time2:units = "hours since 2018-06-17 06:00:00" ;
time2:standard_name = "time" ;
time2:long_name = "forecast period (end of reporting period)" ;
time2:calendar = "gregorian" ;
float time2_bnds(time2, bnds) ;
float rlat(rlat) ;
rlat:axis = "Y" ;
rlat:units = "degrees" ;
rlat:standard_name = "grid_latitude" ;
rlat:long_name = "latitude on rotated pole grid at cell centres" ;
rlat:valid_max = 90.f ;
rlat:valid_min = -90.f ;
float rlon(rlon) ;
rlon:axis = "X" ;
rlon:units = "degrees" ;
rlon:standard_name = "grid_longitude" ;
rlon:long_name = "longitude on rotated pole grid at cell centres" ;
rlon:valid_max = 360.f ;
rlon:valid_min = 0.f ;
float latitude(rlat, rlon) ;
latitude:bounds = "latitude_bnds" ;
latitude:units = "degrees_north" ;
latitude:standard_name = "latitude" ;
latitude:long_name = "geographic latitude at cell centres" ;
latitude:valid_max = 90.f ;
latitude:valid_min = -90.f ;
float latitude_bnds(rlat, rlon, bnds_4) ;
float longitude(rlat, rlon) ;
longitude:bounds = "longitude_bnds" ;
longitude:units = "degrees_east" ;
longitude:standard_name = "longitude" ;
longitude:long_name = "geographic longitude at cell centres" ;
longitude:valid_max = 360.f ;
longitude:valid_min = 0.f ;
float longitude_bnds(rlat, rlon, bnds_4) ;
float orog_model(rlat, rlon) ;
orog_model:standard_name = "surface_altitude" ;
orog_model:long_name = "altitude of model orography" ;
orog_model:stash_model = 1 ;
orog_model:stash_section = 0 ;
orog_model:stash_item = 33 ;
orog_model:units = "m" ;
orog_model:valid_min = -150.f ;
orog_model:valid_max = 4000.f ;
orog_model:_FillValue = -1.073742e+09f ;
orog_model:coordinates = "latitude longitude" ;
orog_model:grid_mapping = "rotated_pole" ;
orog_model:actual_range = -58.91967f, 2800.626f ;
orog_model:cell_methods = "time3: mean" ;
char rotated_pole ;
rotated_pole:grid_mapping_name = "rotated_latitude_longitude" ;
rotated_pole:grid_north_pole_latitude = 49.55f ;
rotated_pole:grid_north_pole_longitude = 171.77f ;
rotated_pole:north_pole_grid_longitude = 0.f ;
float sfc_air_press(time0, rlat, rlon) ;
sfc_air_press:standard_name = "air_pressure" ;
sfc_air_press:long_name = "surface pressure at model surface" ;
sfc_air_press:stash_model = 1 ;
sfc_air_press:stash_section = 0 ;
sfc_air_press:stash_item = 409 ;
sfc_air_press:units = "Pa" ;
sfc_air_press:valid_min = 60000.f ;
sfc_air_press:valid_max = 110000.f ;
sfc_air_press:_FillValue = -1.073742e+09f ;
sfc_air_press:coordinates = "latitude longitude" ;
sfc_air_press:grid_mapping = "rotated_pole" ;
sfc_air_press:actual_range = 70902.12f, 102833.1f ;
float sfc_dw_lw_flux(time1, rlat, rlon) ;
sfc_dw_lw_flux:standard_name = "surface_downward_longwave_flux" ;
sfc_dw_lw_flux:long_name = "downward longwave flux at the surface" ;
sfc_dw_lw_flux:stash_model = 1 ;
sfc_dw_lw_flux:stash_section = 2 ;
sfc_dw_lw_flux:stash_item = 207 ;
sfc_dw_lw_flux:units = "W m-2" ;
sfc_dw_lw_flux:valid_min = 0.f ;
sfc_dw_lw_flux:valid_max = 2000.f ;
sfc_dw_lw_flux:_FillValue = -1.073742e+09f ;
sfc_dw_lw_flux:coordinates = "latitude longitude" ;
sfc_dw_lw_flux:grid_mapping = "rotated_pole" ;
sfc_dw_lw_flux:actual_range = 144.8594f, 415.6719f ;
float sfc_dw_sw_flux(time1, rlat, rlon) ;
sfc_dw_sw_flux:standard_name = "surface_downward_shortwave_flux" ;
sfc_dw_sw_flux:long_name = "downward shortwave flux at the surface" ;
sfc_dw_sw_flux:stash_model = 1 ;
sfc_dw_sw_flux:stash_section = 1 ;
sfc_dw_sw_flux:stash_item = 235 ;
sfc_dw_sw_flux:units = "W m-2" ;
sfc_dw_sw_flux:valid_min = 0.f ;
sfc_dw_sw_flux:valid_max = 2000.f ;
sfc_dw_sw_flux:_FillValue = -1.073742e+09f ;
sfc_dw_sw_flux:coordinates = "latitude longitude" ;
sfc_dw_sw_flux:grid_mapping = "rotated_pole" ;
sfc_dw_sw_flux:actual_range = 0.f, 771.4844f ;
float sfc_merid_wind(time0, rlat, rlon) ;
sfc_merid_wind:standard_name = "northward_wind" ;
sfc_merid_wind:long_name = "true northward (meridional) wind at 10m" ;
sfc_merid_wind:stash_model = 1 ;
sfc_merid_wind:stash_section = 3 ;
sfc_merid_wind:stash_item = 210 ;
sfc_merid_wind:units = "m s-1" ;
sfc_merid_wind:valid_min = -100.f ;
sfc_merid_wind:valid_max = 100.f ;
sfc_merid_wind:_FillValue = -1.073742e+09f ;
sfc_merid_wind:coordinates = "latitude longitude" ;
sfc_merid_wind:grid_mapping = "rotated_pole" ;
sfc_merid_wind:actual_range = -28.3125f, 25.6875f ;
float sfc_rh(time0, rlat, rlon) ;
sfc_rh:standard_name = "relative_humidity" ;
sfc_rh:long_name = "relative humidity at 1.5m" ;
sfc_rh:stash_model = 1 ;
sfc_rh:stash_section = 3 ;
sfc_rh:stash_item = 245 ;
sfc_rh:units = "1" ;
sfc_rh:valid_min = 0.f ;
sfc_rh:valid_max = 1.f ;
sfc_rh:_FillValue = -1.073742e+09f ;
sfc_rh:coordinates = "latitude longitude" ;
sfc_rh:grid_mapping = "rotated_pole" ;
sfc_rh:actual_range = 0.22875f, 1.15375f ;
float sfc_snow_amount(time0, rlat, rlon) ;
sfc_snow_amount:standard_name = "surface_snow_amount" ;
sfc_snow_amount:long_name = "surface snow amount excluding that on vegetation" ;
sfc_snow_amount:stash_model = 1 ;
sfc_snow_amount:stash_section = 0 ;
sfc_snow_amount:stash_item = 23 ;
sfc_snow_amount:units = "kg m-2" ;
sfc_snow_amount:valid_min = 0.f ;
sfc_snow_amount:valid_max = 100000.f ;
sfc_snow_amount:_FillValue = -1.073742e+09f ;
sfc_snow_amount:coordinates = "latitude longitude" ;
sfc_snow_amount:grid_mapping = "rotated_pole" ;
sfc_snow_amount:actual_range = 0.f, 41577.25f ;
float sfc_snow_melt(time0, rlat, rlon) ;
sfc_snow_melt:standard_name = "surface_snow_melt_flux" ;
sfc_snow_melt:long_name = "land snow melt rate" ;
sfc_snow_melt:stash_model = 1 ;
sfc_snow_melt:stash_section = 8 ;
sfc_snow_melt:stash_item = 231 ;
sfc_snow_melt:units = "kg m-2 s-1" ;
sfc_snow_melt:valid_min = 0.f ;
sfc_snow_melt:valid_max = 100.f ;
sfc_snow_melt:_FillValue = -1.073742e+09f ;
sfc_snow_melt:coordinates = "latitude longitude" ;
sfc_snow_melt:grid_mapping = "rotated_pole" ;
sfc_snow_melt:actual_range = 0.f, 0.002179627f ;
float sfc_temp(time0, rlat, rlon) ;
sfc_temp:standard_name = "air_temperature" ;
sfc_temp:long_name = "air temperature at 1.5m" ;
sfc_temp:stash_model = 1 ;
sfc_temp:stash_section = 3 ;
sfc_temp:stash_item = 236 ;
sfc_temp:units = "K" ;
sfc_temp:valid_min = 230.f ;
sfc_temp:valid_max = 333.f ;
sfc_temp:_FillValue = -1.073742e+09f ;
sfc_temp:coordinates = "latitude longitude" ;
sfc_temp:grid_mapping = "rotated_pole" ;
sfc_temp:actual_range = 251.9062f, 293.9844f ;
float sfc_zonal_wind(time0, rlat, rlon) ;
sfc_zonal_wind:standard_name = "eastward_wind" ;
sfc_zonal_wind:long_name = "true eastward (zonal) wind at 10m" ;
sfc_zonal_wind:stash_model = 1 ;
sfc_zonal_wind:stash_section = 3 ;
sfc_zonal_wind:stash_item = 209 ;
sfc_zonal_wind:units = "m s-1" ;
sfc_zonal_wind:valid_min = -100.f ;
sfc_zonal_wind:valid_max = 100.f ;
sfc_zonal_wind:_FillValue = -1.073742e+09f ;
sfc_zonal_wind:coordinates = "latitude longitude" ;
sfc_zonal_wind:grid_mapping = "rotated_pole" ;
sfc_zonal_wind:actual_range = -20.3125f, 28.9375f ;
float sum_rain_amount(time2, rlat, rlon) ;
sum_rain_amount:standard_name = "rainfall_amount" ;
sum_rain_amount:long_name = "rainfall amount from all processes" ;
sum_rain_amount:stash_model = 1 ;
sum_rain_amount:stash_section = 4 ;
sum_rain_amount:stash_item = 201 ;
sum_rain_amount:units = "kg m-2" ;
sum_rain_amount:valid_min = 0.f ;
sum_rain_amount:valid_max = 200.f ;
sum_rain_amount:_FillValue = -1.073742e+09f ;
sum_rain_amount:coordinates = "latitude longitude" ;
sum_rain_amount:grid_mapping = "rotated_pole" ;
sum_rain_amount:cell_methods = "time2: sum" ;
sum_rain_amount:actual_range = 0.f, 118.7461f ;
float sum_snowfall_amount(time2, rlat, rlon) ;
sum_snowfall_amount:standard_name = "lwe_thickness_of_snowfall_amount" ;
sum_snowfall_amount:long_name = "snowfall amount from all processes" ;
sum_snowfall_amount:stash_model = 1 ;
sum_snowfall_amount:stash_section = 4 ;
sum_snowfall_amount:stash_item = 202 ;
sum_snowfall_amount:units = "kg m-2" ;
sum_snowfall_amount:valid_min = 0.f ;
sum_snowfall_amount:valid_max = 200.f ;
sum_snowfall_amount:_FillValue = -1.073742e+09f ;
sum_snowfall_amount:coordinates = "latitude longitude" ;
sum_snowfall_amount:grid_mapping = "rotated_pole" ;
sum_snowfall_amount:cell_methods = "time2: sum" ;
sum_snowfall_amount:actual_range = 0.f, 11.19141f ;
float time0(time0) ;
time0:standard_name = "time" ;
time0:long_name = "forecast period" ;
time0:calendar = "gregorian" ;
time0:units = "hours since 2018-06-17 06:00:00" ;
time0:axis = "T" ;
float time1(time1) ;
time1:standard_name = "time" ;
time1:long_name = "forecast period" ;
time1:calendar = "gregorian" ;
time1:units = "hours since 2018-06-17 06:00:00" ;
time1:axis = "T" ;
// global attributes:
:NCO = "4.6.8" ;
:actual_range = 0.f, 118.7461f ;
:comment = "NIWA NZCSM LAM EPS 3 is the UM10.4/PS36/GA6.0 based NZCSM suite." ;
:data_assimilation_method = "Pseudo Analysis" ;
:dynamical_core = "end_game" ;
:forecast_reference_time = "2018-06-17 06:00:00" ;
:grid_mapping_name = "rotated_latitude_longitude" ;
:grid_north_pole_latitude = 49.55 ;
:grid_north_pole_longitude = 171.77 ;
:history = "Applied NZCSM 2 paramater hourly rainfall correction surface (to VCSN)\n",
"Sun Jun 17 13:16:26 2018: ncks -O -x -v time3 -o tn_2018061706-utc_nzcsm.nc tmp_notime3_tn_2018061706-utc_nzcsm.nc\n",
"Sun Jun 17 13:16:10 2018: ncwa -O -a time3 -o tmp_notime3_tn_2018061706-utc_nzcsm.nc raw_tn_2018061706-utc_nzcsm.nc\n",
"Sun Jun 17 13:15:57 2018: ncks -O -d rlon,250,990 -d rlat,110,1080 -o raw_tn_2018061706-utc_nzcsm.nc raw_tn_2018061706-utc_nzcsm.nc\n",
"Sun Jun 17 13:15:19 2018: ncap2 -O -s sum_total_precip=sum_rain_amount+sum_snowfall_amount /niwa/oper/ecox_oper/cylc-run/niwa1-aa179/share/cycle/20180617T06/output/tn_2018061706-utc_nzcsm.nc /niwa/oper/ecox_oper/cylc-run/niwa1-aa179/share/cycle/20180617T06/output/tn_2018061706-utc_nzcsm.nc\n",
"UM fields file converted by um2netcdf-3.2.1 (2017-11-30, x86_64/Linux/gcc)" ;
:input_uri = "/niwa/oper/ecox_oper/cylc-run/niwa1-aa179/share/cycle/20180617T06/output/tn_2018061706-utc_nzcsm.um" ;
:institution = "NIWA" ;
:met_office_ps = "36" ;
:model_name = "nzcsm" ;
:nco_openmp_thread_number = 1 ;
:niwa_eps = "3" ;
:references = "http://matiu/~ecoconnect_admin/eco-docs/DataSet_Definitions/ (needs updating)" ;
:rose_id = "niwa1-aa179" ;
:title = "nzcsm sub-set output for topnet (tn*.nc)" ;
:um_version_number = 1004 ;
:valid_max = 200. ;
:valid_min = 0. ;
:Conventions = "CF-1.5" ;
}

#Gabriella you are correct. ncrcat will concatenate only record variables. Convert your input file from netCDF3 to netCDF4 and make all time dimensions record dimensions then it should work, e.g.,
netcdf mlt_rcd {
dimensions:
time1=unlimited;
time2=unlimited;
time3=unlimited;
variables:
int var1(time1);
int var2(time2);
int var3(time3);
data:
var1=1;
var2=2,2;
var3=3,3,3;
} // end root group
zender#aerosol:~/nco$ ncgen -k netCDF-4 -b -o ~/nco/data/mlt_rcd.nc ~/nco/data/mlt_rcd.cdl
zender#aerosol:~/nco$ ncrcat -O -p ~/nco/data mlt_rcd.nc mlt_rcd.nc ~/foo.nc
zender#aerosol:~/nco$ ncks ~/foo.nc
netcdf foo {
dimensions:
time1 = UNLIMITED ; // (2 currently)
time2 = UNLIMITED ; // (4 currently)
time3 = UNLIMITED ; // (6 currently)
variables:
int var1(time1) ;
int var2(time2) ;
int var3(time3) ;
// global attributes:
:history = "Sun Jul 8 09:55:16 2018: ncrcat -O -p /Users/zender/nco/data mlt_rcd.nc mlt_rcd.nc /Users/zender/foo.nc" ;
:NCO = "netCDF Operators version 4.7.6-alpha03 (Homepage = http://nco.sf.net, Code = http://github.com/nco/nco)" ;
data:
var1 = 1, 1 ;
var2 = 2, 2, 2, 2 ;
var3 = 3, 3, 3, 3, 3, 3 ;
} // group /
zender#aerosol:~/nco$

Related

Libavcodec mpeg4 avi encoding framerate and timebase problem

I try to generate a video with a timebase more precise than the 1/fps (camera frame rate are not constant). But the generated AVI does not seem to take into account the framerate that I indicate.
#include <iostream>
extern "C" {
#include "libavformat/avformat.h"
#include "libavcodec/avcodec.h"
}
#pragma comment(lib,"avcodec.lib")
#pragma comment(lib,"avformat.lib")
constexpr int TIMEFACTOR = 10;
static void encodeFrame(AVCodecContext *avctx, AVFormatContext *ctx, AVFrame* frame)
{
int ret = avcodec_send_frame(avctx, frame);
AVPacket packet;
av_init_packet(&packet);
ret = 0;
while (ret >= 0) {
ret = avcodec_receive_packet(avctx, &packet);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
return; // nothing to write
};
//packet.pts = (frame) ? frame->pts : packet.pts;
av_packet_rescale_ts(&packet, avctx->time_base, ctx->streams[0]->time_base);
packet.duration = TIMEFACTOR;
av_interleaved_write_frame(ctx, &packet);
av_packet_unref(&packet);
}
}
static void fill_yuv_frame(AVFrame* frame, int width, int height, int frameId)
{
// Y
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
frame->data[0][y * frame->linesize[0] + x] = x + y + frameId * 3;
}
}
// Cb and Cr
for (int y = 0; y < height / 2; y++) {
for (int x = 0; x < width / 2; x++) {
frame->data[1][y * frame->linesize[1] + x] = 128 + y + frameId * 2;
frame->data[2][y * frame->linesize[2] + x] = 64 + x + frameId * 5;
}
}
}
int main(int argc, char** argv)
{
const char filename[] = "output.avi";
const char encoder[] = "mpeg4";
constexpr int WIDTH = 640;
constexpr int HEIGHT = 480;
av_log_set_level(AV_LOG_DEBUG);
//delete file because libavcodec reload file
remove(filename);
AVFormatContext* ofmtCtx;
int ret = avformat_alloc_output_context2(&ofmtCtx, NULL, "avi", filename);
AVCodec* avcodec = avcodec_find_encoder_by_name(encoder);
AVCodecContext* avctx = avcodec_alloc_context3(avcodec);
avctx->width = WIDTH ;
avctx->height = HEIGHT ;
avctx->sample_aspect_ratio = { 1, 1 };
avctx->pix_fmt = AV_PIX_FMT_YUV420P; //Do not work with other type
avctx->codec_id = AV_CODEC_ID_MPEG4;
avctx->bit_rate = 4 * 1000 * 1000;
avctx->time_base = av_make_q(1, 25 * TIMEFACTOR);
avctx->framerate = av_make_q(25, 1);
avctx->ticks_per_frame = TIMEFACTOR;
avctx->gop_size = 10;
avctx->max_b_frames = 1;
AVStream* m_outStream = avformat_new_stream(ofmtCtx, NULL);
ret = avcodec_open2(avctx, avcodec, NULL);
ret = avcodec_parameters_from_context(m_outStream->codecpar, avctx);
m_outStream->time_base = avctx->time_base;
m_outStream->r_frame_rate = avctx->framerate;
m_outStream->avg_frame_rate = avctx->framerate;
ret = avio_open(&(ofmtCtx->pb),
filename,
AVIO_FLAG_WRITE);
ret = avformat_write_header(ofmtCtx, NULL);
av_dump_format(ofmtCtx, 0, filename, 1);
AVFrame * avframe = av_frame_alloc();
avframe->format = avctx->pix_fmt;
avframe->width = avctx->width;
avframe->height = avctx->height;
ret = av_frame_get_buffer(avframe, 0);
ret = av_frame_make_writable(avframe);
for (int i = 0; i < 25; ++i) {
fflush(stdout);
fill_yuv_frame(avframe, avctx->width, avctx->height, i);
avframe->pts = i * TIMEFACTOR;
encodeFrame(avctx, ofmtCtx, avframe);
}
encodeFrame(avctx, ofmtCtx, NULL);
av_write_trailer(ofmtCtx);
return 0;
}
And this is dump output :
[mpeg4 # 000002AA64FA1880] intra_quant_bias = 0 inter_quant_bias = -64
[file # 000002AA64F69AC0] Setting default whitelist 'file,crypto'
[avi # 000002AA64F73400] reserve_index_space:0 master_index_max_size:256
[avi # 000002AA64F73400] duration_est:36000.000, filesize_est:18.4GiB, master_index_max_size:256
Output #0, avi, to 'output.avi':
Metadata:
ISFT : Lavf58.12.100
Stream #0:0, 0, 1/250: Video: mpeg4, 1 reference frame (FMP4 / 0x34504D46), yuv420p, 640x480 (0x0) [SAR 1:1 DAR 4:3], 0/1, q=2-31, 4000 kb/s, 25 fps, 25 tbr, 250 tbn
But if I open the video in ffmpeg command line fps is 250, and video content 250 frames, with many dropframe.

recursive merge sort repetitive element print

I am facing problem in the below code...
This code is of recursive merge sort but the array which gets printed has repetitive elements from the array.
help me in identifying the problem.
void merge(int arr[], int l, int mid, int h) {
int i = l;
int j = mid + 1;
int k = l;
int b[h + 1];
while (i <= mid && j <= h) {
if (arr[i] < arr[j])
b[k++] = arr[i++];
else
b[k++] = arr[j++];
}
while (i <= mid)
b[k++] = arr[i++];
while (j <= h)
b[k++] = arr[j++];
for (int i = 0; i <= h; i++)
arr[i] = b[i];
}
void Rmerge_sort(int arr[], int l, int h)
{
if (l < h) {
int mid = (h + l) / 2;
Rmerge_sort(arr, l, mid);
Rmerge_sort(arr, mid + 1, h);
merge(arr, l, mid, h);
}
}
int main() {
int arr[10] = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 10 }, n = 10;
Rmerge_sort(arr, 0, n - 1);
for (int i = 0; i < n; i++)
cout << arr[i] << " ";
}
You define array b with size h + 1 instead of h - l + 1. The merge loops copy the elements to the index values l to h, but the final copy loop takes elements from 0 to h, copying elements from an uninitialized part.
Here is a corrected version:
void merge(int arr[], int l, int mid, int h) {
int len = h - l + 1;
int i = l;
int j = mid + 1;
int k = 0;
int b[len];
while (i <= mid && j <= h) {
if (arr[i] < arr[j])
b[k++] = arr[i++];
else
b[k++] = arr[j++];
}
while (i <= mid)
b[k++] = arr[i++];
while (j <= h)
b[k++] = arr[j++];
for (int i = 0; i < len; i++)
arr[l + i] = b[i];
}
Note however that a better approach to this problem is to save only the left half of the slice to merge and to consider h as the index of the first element after the end of the slice. This avoid confusing and error prone +1/-1 adjustments and reduces the number of copies:
void merge(int arr[], int low, int mid, int hi) {
int len1 = mid - lo;
int b[len1];
int i, j, k;
for (i = 0; i < len1; i++)
b[i] = a[low + i];
for (i = 0, j = mid, k = lo; i < len;) {
if (j >= hi || arr[i] <= arr[j])
arr[k++] = b[i++];
else
arr[k++] = arr[j++];
}
}
void Rmerge_sort(int arr[], int low, int hi) {
if (hi - low > 1) {
int mid = low + (hi - low) / 2; // avoid arithmetic overflow
Rmerge_sort(arr, low, mid);
Rmerge_sort(arr, mid, hi);
merge(arr, low, mid, hi);
}
}
int main() {
int arr[10] = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 10 };
int n = sizeof(arr) / sizeof(arr[0]);
Rmerge_sort(arr, 0, n);
for (int i = 0; i < n; i++)
cout << arr[i] << " ";
}

NCO: Extract a variable from NetCDF file using NCO ncks

I am trying to extract a variable from a multi-variable netcdf file, by entering the command:
ncks -v ta temp1.nc out.nc
However then I look at the out.nc header, all the variables are still there.
The headers of both temp1.nc and out.nc are below:
--- temp1.nc header ---
dimensions:
time = UNLIMITED ; // (124 currently)
lon = 256 ;
bnds = 2 ;
lat = 128 ;
lev = 40 ;
variables:
double time(time) ;
time:standard_name = "time" ;
time:long_name = "time" ;
time:units = "days since 1850-1-1" ;
time:calendar = "365_day" ;
time:axis = "T" ;
double lon(lon) ;
lon:standard_name = "longitude" ;
lon:long_name = "longitude" ;
lon:units = "degrees_east" ;
lon:axis = "X" ;
lon:bounds = "lon_bnds" ;
double lon_bnds(lon, bnds) ;
double lat(lat) ;
lat:standard_name = "latitude" ;
lat:long_name = "latitude" ;
lat:units = "degrees_north" ;
lat:axis = "Y" ;
lat:bounds = "lat_bnds" ;
double lat_bnds(lat, bnds) ;
double p0 ;
p0:long_name = "reference pressure" ;
p0:units = "Pa" ;
double lev(lev) ;
lev:standard_name = "atmosphere_hybrid_sigma_pressure_coordinat
lev:axis = "Z" ;
lev:positive = "down" ;
lev:long_name = "hybrid sigma pressure coordinate" ;
lev:units = "1" ;
lev:formula_terms = "a: a b: b p0: p0 ps: ps" ;
lev:bounds = "lev_bnds" ;
lev:formula = "p = a*p0 + b*ps" ;
double lev_bnds(lev, bnds) ;
lev_bnds:standard_name = "atmosphere_hybrid_sigma_pressure_coor
lev_bnds:units = "1" ;
lev_bnds:formula_terms = "a: a_bnds b: b_bnds p0: p0 ps: ps" ;
double a(lev) ;
a:long_name = "vertical coordinate formula term: ap(k)" ;
a:units = "Pa" ;
double b(lev) ;
b:long_name = "vertical coordinate formula term: b(k)" ;
b:units = "1" ;
double a_bnds(lev, bnds) ;
a_bnds:long_name = "vertical coordinate formula term: ap(k+1/2)
a_bnds:units = "Pa" ;
double b_bnds(lev, bnds) ;
b_bnds:long_name = "vertical coordinate formula term: b(k+1/2)"
b_bnds:units = "1" ;
float ps(time, lat, lon) ;
ps:standard_name = "surface_air_pressure" ;
ps:long_name = "Surface Air Pressure" ;
ps:units = "Pa" ;
ps:comment = "surface pressure, not mean sea level pressure" ;
ps:original_units = "hPa" ;
ps:history = "2011-10-17T12:45:37Z altered by CMOR";
ps:cell_measures = "area: areacella" ;
float ta(time, lev, lat, lon) ;
ta:standard_name = "air_temperature" ;
ta:long_name = "Air Temperature" ;
ta:units = "K" ;
ta:_FillValue = 1.e+20f ;
ta:missing_value = 1.e+20f ;
ta:original_name = "T" ;
ta:cell_measures = "area: areacella" ;
ta:history = "2011-10-17T12:45:37Z altered by CMOR ;
// global attributes:
--- out.nc header ---
dimensions:
lev = 40 ;
bnds = 2 ;
lat = 128 ;
lon = 256 ;
time = UNLIMITED ; // (124 currently)
variables:
double a(lev) ;
a:long_name = "vertical coordinate formula term: ap(k)" ;
a:units = "Pa" ;
double a_bnds(lev, bnds) ;
a_bnds:long_name = "vertical coordinate formula term: ap(k+1/2)" ;
a_bnds:units = "Pa" ;
double b(lev) ;
b:long_name = "vertical coordinate formula term: b(k)" ;
b:units = "1" ;
double b_bnds(lev, bnds) ;
b_bnds:long_name = "vertical coordinate formula term: b(k+1/2)" ;
b_bnds:units = "1" ;
double lat(lat) ;
lat:standard_name = "latitude" ;
lat:long_name = "latitude" ;
lat:units = "degrees_north" ;
lat:axis = "Y" ;
lat:bounds = "lat_bnds" ;
double lat_bnds(lat, bnds) ;
double lev(lev) ;
lev:standard_name = "atmosphere_hybrid_sigma_pressure_coordinate" ;
lev:axis = "Z" ;
lev:positive = "down" ;
lev:long_name = "hybrid sigma pressure coordinate" ;
lev:units = "1" ;
lev:formula_terms = "a: a b: b p0: p0 ps: ps" ;
lev:bounds = "lev_bnds" ;
lev:formula = "p = a*p0 + b*ps" ;
double lev_bnds(lev, bnds) ;
lev_bnds:standard_name = "atmosphere_hybrid_sigma_pressure_coordinate" ;
lev_bnds:units = "1" ;
lev_bnds:formula_terms = "a: a_bnds b: b_bnds p0: p0 ps: ps" ;
double lon(lon) ;
lon:standard_name = "longitude" ;
lon:long_name = "longitude" ;
lon:units = "degrees_east" ;
lon:axis = "X" ;
lon:bounds = "lon_bnds" ;
double lon_bnds(lon, bnds) ;
double p0 ;
p0:long_name = "reference pressure" ;
p0:units = "Pa" ;
float ps(time, lat, lon) ;
ps:standard_name = "surface_air_pressure" ;
ps:long_name = "Surface Air Pressure" ;
ps:units = "Pa" ;
ps:comment = "surface pressure, not mean sea level pressure" ;
ps:original_units = "hPa" ;
ps:history = "2011-10-17T12:45:37Z altered by CMOR" ;
ps:cell_measures = "area: areacella" ;
float ta(time, lev, lat, lon) ;
ta:standard_name = "air_temperature" ;
ta:long_name = "Air Temperature" ;
ta:units = "K" ;
ta:_FillValue = 1.e+20f ;
ta:missing_value = 1.e+20f ;
ta:original_name = "T" ;
ta:cell_measures = "area: areacella" ;
ta:history = "2011-10-17T12:45:37Z altered by CMOR" ;
double time(time) ;
time:standard_name = "time" ;
time:long_name = "time" ;
time:units = "days since 1850-1-1" ;
time:calendar = "365_day" ;
time:axis = "T" ;
// global attributes:
I expected to have only ta on out.nc. I don't get any error message from ncks.
What am I doing wrong here? I appreciate any help.
Thank you.
This behavior occurs because, by default, NCO extracts all the variables "associated" with a requested variable. That way users get everything they need without having to look for it themselves. In other words, it's a feature, not a bug. To extract only the variables explicitly requested, use the -C switch, documented here, e.g.
ncks -C -v ta temp1.nc out.nc
The docs also show how to strip away the CF-conventions-associated variables, while retainining, say, the coordinates, with a variety of longer options.
Just to give another command line alterative to NCO, you can also use CDO,
the command is:
cdo selvar,variable_name input.nc output.nc
if you don't have it, you can install it with ubuntu, mint etc with
sudo apt-get install cdo

MPI_Wtime() returns strange numbers

When I use MPI_Wtime() to record the computation time, it returns several weird numbers, which seems not correct. My code is very simple:
#include <stdio.h>
#include "mpi.h"
int main(int argc,char *argv[])
{
int i,sum,total;
int size,rank,start,end,sumGlobal;
double t1,t2;
total = 10000;
t1 = MPI_Wtime();
MPI_Init(&argc,&argv);
MPI_Comm_size(MPI_COMM_WORLD,&size);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
start = rank*(total/size)+1;
if (rank==(size-1))
{
end = total;
}
else
{
end = start+(total/size)-1;
}
sumGlobal = 0;
sum = 0;
for (i=start;i<=end;i++)
{
sum += i;
}
MPI_Reduce(&sum,&sumGlobal,1,MPI_INT,MPI_SUM,0,MPI_COMM_WORLD);
t2 = MPI_Wtime();
printf("rank = %d,sum = %d,sumGlobal = %d,time=%f\n",rank,sum,sumGlobal,t2-t1);
MPI_Finalize();
return 0;
}
The running result is (use 16 cores):
rank = 0,sum = 195625,sumGlobal = 50005000,time = 1520044462.143606
rank = 1,sum = 586250,sumGlobal = 0,time = 1520044462.143662
rank = 3,sum = 1367500,sumGlobal = 0,time = 1520044462.143665
rank = 4,sum = 1758125,sumGlobal = 0,time = 1520044462.143610
rank = 5,sum = 2148750,sumGlobal = 0,time = 1520044462.143651
rank = 6,sum = 2539375,sumGlobal = 0,time = 1520044462.143608
rank = 7,sum = 2930000,sumGlobal = 0,time = 1520044462.143604
rank = 9,sum = 3711250,sumGlobal = 0,time = 1520044462.143647
rank = 10,sum = 4101875,sumGlobal = 0,time = 1520044462.143655
rank = 11,sum = 4492500,sumGlobal = 0,time = 1520044462.143606
rank = 12,sum = 4883125,sumGlobal = 0,time = 1520044462.143614
rank = 13,sum = 5273750,sumGlobal = 0,time = 1520044462.143672
rank = 14,sum = 5664375,sumGlobal = 0,time = 1520044462.143643
rank = 15,sum = 6055000,sumGlobal = 0,time = 1520044462.143605
rank = 2,sum = 976875,sumGlobal = 0,time = 1520044462.143665
rank = 8,sum = 3320625,sumGlobal = 0,time = 1520044462.143652
As you can see, the "time" values are very strange. So how to fix it? Thank you.
Your program is incorrect with respect to the MPI standard :
you simply cannot use MPI_Wtime() before MPI_Init() (nor after MPI_Finalize() fwiw).
Moving the t1 initialization should fix the issue.

OpenCL RGB->HSL and back

Ive been through every resource and cant fix my problem.
My host code calls the rgb2hsl kernel, then calls the hsl2rgb kernel. I should end up with the same image that I started with, but I do not. My new image hue is off in certain areas.
The red areas should not be there.
Here is the screen shot of what happens:
Here is the original picture
Here is the code:
#define E .0000001f
bool fEqual(float x, float y)
{
return (x+E > y && x-E < y);
}
__kernel void rgb2hsl(__global float *values, int numValues)
{
// thread index and total
int idx = get_global_id(0);
int idxVec3 = idx*3;
float3 gMem;
if (idx < numValues)
{
gMem.x = values[idxVec3];
gMem.y = values[idxVec3+1];
gMem.z = values[idxVec3+2];
}
barrier(CLK_LOCAL_MEM_FENCE);
gMem /= 255.0f; //convert from 256 color to float
//calculate chroma
float M = max(gMem.x, gMem.y);
M = max(M, gMem.z);
float m = min(gMem.x, gMem.y);
m = min(m, gMem.z);
float chroma = M-m; //calculate chroma
float lightness = (M+m)/2.0f;
float saturation = chroma/(1.0f-fabs(2.0f*lightness-1.0f));
float hue = 0;
if (fEqual(gMem.x, M))
hue = (int)((gMem.y - gMem.z)/chroma) % 6;
if (fEqual(gMem.y, M))
hue = (((gMem.z - gMem.x))/chroma) + 2;
if (fEqual(gMem.z, M))
hue = (((gMem.x - gMem.y))/chroma) + 4;
hue *= 60.0f;
barrier(CLK_LOCAL_MEM_FENCE);
if (idx < numValues)
{
values[idxVec3] = hue;
values[idxVec3+1] = saturation;
values[idxVec3+2] = lightness;
}
}
__kernel void hsl2rgb(__global float *values, int numValues)
{
// thread index and total
int idx = get_global_id(0);
int idxVec3 = idx*3;
float3 gMem;
if (idx < numValues)
{
gMem.x = values[idxVec3];
gMem.y = values[idxVec3+1];
gMem.z = values[idxVec3+2];
}
barrier(CLK_LOCAL_MEM_FENCE);
float3 rgb = (float3)(0,0,0);
//calculate chroma
float chroma = (1.0f - fabs( (float)(2.0f*gMem.z - 1.0f) )) * gMem.y;
float H = gMem.x/60.0f;
float x = chroma * (1.0f - fabs( fmod(H, 2.0f) - 1.0f ));
switch((int)H)
{
case 0:
rgb = (float3)(chroma, x, 0);
break;
case 1:
rgb = (float3)(x, chroma, 0);
break;
case 2:
rgb = (float3)(0, chroma, x);
break;
case 3:
rgb = (float3)(0, x, chroma);
break;
case 4:
rgb = (float3)(x, 0, chroma);
break;
case 5:
rgb = (float3)(chroma, 0, x);
break;
default:
rgb = (float3)(0, 0, 0);
}
barrier(CLK_LOCAL_MEM_FENCE);
rgb += gMem.z - .5f*chroma;
rgb *= 255;
if (idx < numValues)
{
values[idxVec3] = rgb.x;
values[idxVec3+1] = rgb.y;
values[idxVec3+2] = rgb.z;
}
}
The problem was this line:
hue = (int)((gMem.y - gMem.z)/chroma) % 6;
It should be
hue = fmod((gMem.y - gMem.z)/chroma, 6.0f);
I did some more changes to remove artifacts:
#define E .0000001f
bool fEqual(float x, float y)
{
return (x+E > y && x-E < y);
}
__kernel void rgb2hsl(__global float *values, int numValues)
{
// thread index and total
int idx = get_global_id(0);
int idxVec3 = idx*3;
float3 gMem;
if (idx < numValues)
{
gMem.x = values[idxVec3];
gMem.y = values[idxVec3+1];
gMem.z = values[idxVec3+2];
}
barrier(CLK_LOCAL_MEM_FENCE);
gMem /= 255.0f; //convert from 256 color to float
//calculate chroma
float M = max(gMem.x, gMem.y);
M = max(M, gMem.z);
float m = min(gMem.x, gMem.y);
m = min(m, gMem.z);
float chroma = M-m; //calculate chroma
float lightness = (M+m)/2.0f;
float saturation = chroma/(1.0f-fabs(2.0f*lightness-1.0f));
float hue = 0;
if (fEqual(gMem.x, M))
hue = fmod((gMem.y - gMem.z)/chroma, 6.0f);
if (fEqual(gMem.y, M))
hue = (((gMem.z - gMem.x))/chroma) + 2;
if (fEqual(gMem.z, M))
hue = (((gMem.x - gMem.y))/chroma) + 4;
hue *= 60.0f;
barrier(CLK_LOCAL_MEM_FENCE);
if (M == m)
hue = saturation = 0;
barrier(CLK_GLOBAL_MEM_FENCE);
if (idx < numValues)
{
//NOTE: ARTIFACTS SHOW UP if we do not cast to integer!
values[idxVec3] = (int)hue;
values[idxVec3+1] = saturation;
values[idxVec3+2] = lightness;
}
}

Resources