예제 #1
0
파일: nco_aux.c 프로젝트: wenshanw/nco
int /* [enm] Return status */
nco_get_dmn_info
(int nc_id,
 int var_id,
 char dmn_nm[],
 int *dimid,
 long *dmn_sz)
{
  /* Purpose: Get dimension information associated with specified variable
     In our case, this is lat or lon---they are presumed to be identical */
  
  int rcd=NC_NOERR;
  
  nc_type var_typ;                   /* variable type */
  int var_dimid[NC_MAX_VAR_DIMS];    /* dimension ids */
  int var_att_nbr;                      /* number of attributes */
  int var_dmn_nbr;                      /* number of dims */
  
  /* Get dimension information */
  rcd=nco_inq_var(nc_id,var_id,0,&var_typ,&var_dmn_nbr,var_dimid,&var_att_nbr);
  if(rcd == NC_NOERR){
    *dimid=var_dimid[0];
    rcd=nco_inq_dimlen(nc_id,var_dimid[0],dmn_sz);
    rcd=nco_inq_dimname(nc_id,var_dimid[0],dmn_nm);
  } /* endif */

  if(rcd != NC_NOERR) nco_err_exit(rcd,"nco_get_dmn_info() unable to get dimension information");

  return rcd;
} /* end nco_get_dmn_info() */
예제 #2
0
파일: nco_dmn_utl.c 프로젝트: wenshanw/nco
nm_id_sct * /* O [sct] List of dimensions associated with input variable list */
nco_dmn_lst_ass_var /* [fnc] Create list of all dimensions associated with input variable list */
(const int nc_id, /* I [id] netCDF input-file ID */
 const nm_id_sct * const var, /* I [sct] Variable list */
 const int nbr_var, /* I [nbr] Number of variables in list */
 int * const nbr_dmn) /* O [nbr] Number of dimensions associated with input variable list */
{
  /* Purpose: Create list of all dimensions associated with input variable list */

  nco_bool dmn_has_been_placed_on_list;

  char dmn_nm[NC_MAX_NAME];

  int dmn_id[NC_MAX_DIMS];
  int idx_dmn_in;
  int idx_var;
  int idx_var_dmn;
  int idx_dmn_lst;
  int nbr_dmn_in;
  int nbr_var_dmn;
  
  nm_id_sct *dmn;

  *nbr_dmn=0;

  /* Get number of dimensions */
  (void)nco_inq(nc_id,&nbr_dmn_in,(int *)NULL,(int *)NULL,(int *)NULL);

  /* Number of input dimensions is upper bound on number of output dimensions */
  dmn=(nm_id_sct *)nco_malloc(nbr_dmn_in*sizeof(nm_id_sct));
  
  /* ...For each dimension in file... */
  for(idx_dmn_in=0;idx_dmn_in<nbr_dmn_in;idx_dmn_in++){
    /* ...begin search for dimension in dimension list by... */
    dmn_has_been_placed_on_list=False;
    /* ...looking through the set of output variables... */
    for(idx_var=0;idx_var<nbr_var;idx_var++){
      /* ...and searching each dimension of each output variable... */
      (void)nco_inq_var(nc_id,var[idx_var].id,(char *)NULL,(nc_type *)NULL,&nbr_var_dmn,dmn_id,(int *)NULL);
      for(idx_var_dmn=0;idx_var_dmn<nbr_var_dmn;idx_var_dmn++){
        /* ...until output variable is found which contains input dimension... */
        if(idx_dmn_in == dmn_id[idx_var_dmn]){
          /* ...then search each member of output dimension list... */
          for(idx_dmn_lst=0;idx_dmn_lst<*nbr_dmn;idx_dmn_lst++){
            /* ...until input dimension is found... */
            if(idx_dmn_in == dmn[idx_dmn_lst].id) break; /* ...then search no further... */
          } /* end loop over idx_dmn_lst */
          /* ...and if dimension was not found on output dimension list... */
          if(idx_dmn_lst == *nbr_dmn){
            /* ...then add dimension to output dimension list... */
            (void)nco_inq_dimname(nc_id,idx_dmn_in,dmn_nm);
            dmn[*nbr_dmn].id=idx_dmn_in;
            dmn[*nbr_dmn].nm=(char *)strdup(dmn_nm);
            (*nbr_dmn)++;
          } /* end if dimension was not found in current output dimension list */
          /* ...call off the dogs for this input dimension... */
          dmn_has_been_placed_on_list=True;
        } /* end if input dimension belongs to this output variable */
        if(dmn_has_been_placed_on_list) break; /* break out of idx_var_dmn to idx_var */
      } /* end loop over idx_var_dmn */
      if(dmn_has_been_placed_on_list) break; /* break out of idx_var to idx_dmn_in */
    } /* end loop over idx_var */
  } /* end loop over idx_dmn_in */

  /* We now have final list of dimensions to extract. Phew. */
  
  /* Free unused space in output dimension list */
  dmn=(nm_id_sct *)nco_realloc((void *)dmn,*nbr_dmn*sizeof(nm_id_sct));
  
  return dmn;
} /* end nco_dmn_lst_ass_var() */
예제 #3
0
파일: nco_dmn_utl.c 프로젝트: wenshanw/nco
int /* O [flg] Dimension exists in scope of group (if rcd != NC_NOERR) */
nco_inq_dmn_grp_id /* [fnc] Return location and ID of named dimension in specified group */
(const int nc_id, /* I [id] netCDF group ID */
 const char * const dmn_nm, /* I [sng] Dimension name */
 int * const dmn_id, /* O [id] Dimension ID in specified group */
 int * const grp_id_dmn) /* O [id] Group ID where dimension visible to specified group is defined */
{
  /* Purpose: Return location and ID of named dimension in specified group
     ncks -O -D 1 -v two_dmn_rec_var ~/nco/data/in_grp.nc ~/foo.nc */

  const char fnc_nm[]="nco_inq_dmn_grp_id()"; /* [sng] Function name */

  const int flg_prn=1; /* [flg] Retrieve all dimensions in all parent groups */        

  int dmn_ids[NC_MAX_DIMS]; /* [nbr] Dimensions IDs array */

  int dmn_idx; /* [idx] Dimension index */
  int dmn_nbr; /* [nbr] Number of dimensions for group */
  int rcd; /* [rcd] Return code */

  nco_bool grp_dfn_fnd=False; /* [flg] Group of definition has been found */

  /* Initialize search to start with specified group */
  *grp_id_dmn=nc_id;

  rcd=nco_inq_dimid_flg(*grp_id_dmn,dmn_nm,dmn_id);
  
  if(nco_dbg_lvl_get() >= nco_dbg_std){
    char *grp_nm_fll; /* [sng] Group name */
    char dmn_nm_lcl[NC_MAX_NAME]; /* [sng] Dimension name */
    size_t grp_nm_fll_lng; /* [nbr] Length of group name */
    (void)nco_inq_grpname_full(*grp_id_dmn,&grp_nm_fll_lng,(char *)NULL);
    grp_nm_fll=(char *)nco_malloc((grp_nm_fll_lng+1L)*sizeof(char));
    (void)nco_inq_grpname_full(*grp_id_dmn,(size_t *)NULL,grp_nm_fll);
    (void)nco_inq_dimids(*grp_id_dmn,&dmn_nbr,dmn_ids,flg_prn);
    (void)fprintf(stdout,"%s: %s nco_inq_dimids() reports following dimensions/IDs are visible to group %s:\n",nco_prg_nm_get(),fnc_nm,grp_nm_fll);
    for(dmn_idx=0;dmn_idx<dmn_nbr;dmn_idx++){
      (void)nco_inq_dimname(*grp_id_dmn,dmn_ids[dmn_idx],dmn_nm_lcl);
      (void)fprintf(stdout,"%s/%d,%s",dmn_nm_lcl,dmn_ids[dmn_idx],(dmn_idx == dmn_nbr-1) ? "\n" : ", ");
    } /* end loop over dmn */
    if(rcd == NC_NOERR) (void)fprintf(stdout,"%s: %s nco_inq_dimid() reports group %s sees dimension %s with ID = %d:\n",nco_prg_nm_get(),fnc_nm,grp_nm_fll,dmn_nm,*dmn_id); else (void)fprintf(stdout,"%s: %s reports group %s does not see dimension %s\n",nco_prg_nm_get(),fnc_nm,grp_nm_fll,dmn_nm);
    if(grp_nm_fll) grp_nm_fll=(char *)nco_free(grp_nm_fll);
  } /* endif dbg */

  /* If dimension is visible to output group, find exactly where it is defined
     Search ancestors until group of definition is found ... */
  while(!grp_dfn_fnd && (rcd == NC_NOERR)){
    /* ... obtain all dimension IDs in current group (_NOT_ in ancestor groups) ... */
    (void)nco_inq_dimids(*grp_id_dmn,&dmn_nbr,dmn_ids,0);
    /* ... and check each against ID of target dimension */
    for(dmn_idx=0;dmn_idx<dmn_nbr;dmn_idx++)
      if(dmn_ids[dmn_idx] == *dmn_id) break;
    
    if(nco_dbg_lvl_get() >= nco_dbg_std){
      char *grp_nm_fll; /* [sng] Group name */
      size_t grp_nm_fll_lng; /* [nbr] Length of group name */
      (void)nco_inq_grpname_full(*grp_id_dmn,&grp_nm_fll_lng,(char *)NULL);
      grp_nm_fll=(char *)nco_malloc((grp_nm_fll_lng+1L)*sizeof(char));
      (void)nco_inq_grpname_full(*grp_id_dmn,(size_t *)NULL,grp_nm_fll);
      (void)fprintf(stdout,"%s: %s reports dimension %s was%s defined in group %s\n",nco_prg_nm_get(),fnc_nm,dmn_nm,(dmn_idx < dmn_nbr) ? "" : " not",grp_nm_fll);
      if(grp_nm_fll) grp_nm_fll=(char *)nco_free(grp_nm_fll);
    } /* endif dbg */
    
    if(dmn_idx < dmn_nbr){
      grp_dfn_fnd=True;
    }else{
      /* Overwrite current group ID with parent group ID */
      rcd=nco_inq_grp_parent_flg(*grp_id_dmn,grp_id_dmn);
    } /* end else */
  } /* end while */
 
  return rcd;

} /* end nco_inq_dmn_grp_id */
예제 #4
0
파일: nco_cnk.c 프로젝트: netbit-au/nckt
void
nco_cnk_sz_set /* [fnc] Set chunksize parameters */
(const int nc_id, /* I [id] netCDF file ID */
 CST_X_PTR_CST_PTR_CST_Y(lmt_all_sct,lmt_all_lst), /* I [sct] Hyperslab limits */
 const int lmt_all_lst_nbr, /* I [nbr] Number of hyperslab limits */
 int * const cnk_map_ptr, /* I/O [enm] Chunking map */
 int * const cnk_plc_ptr, /* I/O [enm] Chunking policy */
 const size_t cnk_sz_scl, /* I [nbr] Chunk size scalar */
 CST_X_PTR_CST_PTR_CST_Y(cnk_sct,cnk), /* I [sct] Chunking information */
 const int cnk_nbr) /* I [nbr] Number of dimensions with user-specified chunking */
{
  /* Purpose: Use chunking map and policy to determine chunksize list */
  const char fnc_nm[]="nco_cnk_sz_set()"; /* [sng] Function name */

  char dmn_nm[NC_MAX_NAME];
  char var_nm[NC_MAX_NAME];

  int *dmn_id;

  int cnk_idx;
  int dmn_idx;
  int cnk_map; /* [enm] Chunking map */
  int cnk_plc; /* [enm] Chunking policy */
  int chk_typ; /* [enm] Checksum type */
  int deflate; /* [enm] Deflate filter is on */
  int dmn_nbr; /* [nbr] Number of dimensions in variable */
  int fl_fmt; /* [enm] Input file format */
  int lmt_idx;
  int lmt_idx_rec=int_CEWI;
  int nbr_dmn_fl; /* [nbr] Number of dimensions in file */
  int rcd_dmn_id;
  int srg_typ; /* [enm] Storage type */
  int var_idx;
  int var_nbr;

  long dmn_sz;

  nco_bool flg_cnk=False; /* [flg] Chunking requested */
  nco_bool is_rec_var; /* [flg] Record variable */
  nco_bool is_chk_var; /* [flg] Checksummed variable */
  nco_bool is_cmp_var; /* [flg] Compressed variable */
  nco_bool is_chunked; /* [flg] Chunked variable */
  nco_bool must_be_chunked; /* [flg] Variable must be chunked */

  nc_type var_typ_dsk;
  
  size_t *cnk_sz; /* [nbr] Chunksize list */
  size_t cnk_sz_dfl; /* [nbr] Chunksize default */

  /* Did user explicitly request chunking? */
  if(cnk_nbr > 0 || cnk_sz_scl > 0UL || *cnk_map_ptr != nco_cnk_map_nil || *cnk_plc_ptr != nco_cnk_plc_nil) flg_cnk=True;

  if(!flg_cnk) return;

  /* Set actual chunk policy and map to defaults as necessary
     This rather arcane procedure saves a few lines of code in calling program
     (because defaults not set there) while maintaining correctness of arguments */
  if(*cnk_map_ptr == nco_cnk_map_nil) *cnk_map_ptr=nco_cnk_map_get((char *)NULL);
  if(*cnk_plc_ptr == nco_cnk_plc_nil) *cnk_plc_ptr=nco_cnk_plc_get((char *)NULL);
  cnk_map=*cnk_map_ptr;
  cnk_plc=*cnk_plc_ptr;

  /* Bail on unsupported options */
  if(cnk_plc == nco_cnk_plc_xpl){
    (void)fprintf(stderr,"%s: ERROR cnk_plc = %s not yet supported\n",prg_nm_get(),nco_cnk_plc_sng_get(cnk_plc));
    nco_exit(EXIT_FAILURE);
  } /* endif */

  /* Does output file support chunking? */
  (void)nco_inq_format(nc_id,&fl_fmt);
  if(fl_fmt != NC_FORMAT_NETCDF4 && fl_fmt != NC_FORMAT_NETCDF4_CLASSIC){
    (void)fprintf(stderr,"%s: WARNING Output file format is %s so chunking request will be ignored\n",prg_nm_get(),nco_fmt_sng(fl_fmt));
    return;
  } /* endif dbg */

  /* Vet input */
  if(cnk_map == nco_cnk_map_scl && cnk_sz_scl <= 0){
    (void)fprintf(stderr,"%s: ERROR cnk_sz_scl = %lu must be greater than 0\n",prg_nm_get(),(unsigned long)cnk_sz_scl);
    nco_exit(EXIT_FAILURE);
  } /* endif cnk_sz_scl */

  if(dbg_lvl_get() >= nco_dbg_fl) (void)fprintf(stderr,"%s: INFO Requested chunking or unchunking\n",prg_nm_get());
  if(dbg_lvl_get() >= nco_dbg_scl){
    (void)fprintf(stderr,"cnk_plc: %s\n",nco_cnk_plc_sng_get(cnk_plc));
    (void)fprintf(stderr,"cnk_map: %s\n",nco_cnk_map_sng_get(cnk_map));
    (void)fprintf(stderr,"cnk_sz_scl: %lu\n",(unsigned long)cnk_sz_scl);
    if(cnk_nbr > 0){
      (void)fprintf(stderr,"idx dmn_nm\tcnk_sz:\n");
      for(cnk_idx=0;cnk_idx<cnk_nbr;cnk_idx++) (void)fprintf(stderr,"%2d %s\t%lu\n",cnk_idx,cnk[cnk_idx]->nm,(unsigned long)cnk[cnk_idx]->sz);
    } /* cnk_nbr == 0 */
  } /* endif dbg */

  /* Get record dimension ID */
  (void)nco_inq(nc_id,&nbr_dmn_fl,&var_nbr,(int *)NULL,&rcd_dmn_id);
  
  /* Find record dimension, if any, in limit structure list first
     This information may be needed below */
  if(rcd_dmn_id != NCO_REC_DMN_UNDEFINED){
    (void)nco_inq_dimname(nc_id,rcd_dmn_id,dmn_nm);
    for(lmt_idx=0;lmt_idx<lmt_all_lst_nbr;lmt_idx++){
      if(!strcmp(dmn_nm,lmt_all_lst[lmt_idx]->dmn_nm)){
	lmt_idx_rec=lmt_idx;
	break;
      } /* end if */
    } /* end loop over limit */
  } /* NCO_REC_DMN_UNDEFINED */

  /* NB: Assumes variable IDs range from [0..var_nbr-1] */
  for(var_idx=0;var_idx<var_nbr;var_idx++){

    /* Initialize storage type for this variable */
    srg_typ=NC_CONTIGUOUS; /* [enm] Storage type */
    cnk_sz=(size_t *)NULL; /* [nbr] Chunksize list */
    is_rec_var=False; /* [flg] Record variable */
    is_chk_var=False; /* [flg] Checksummed variable */
    is_cmp_var=False; /* [flg] Compressed variable */
    is_chunked=False; /* [flg] Chunked variable */

    /* Get type and number of dimensions for variable */
    (void)nco_inq_var(nc_id,var_idx,var_nm,&var_typ_dsk,&dmn_nbr,(int *)NULL,(int *)NULL);
    
    if(dmn_nbr == 0) continue; /* Skip chunking calls for scalars */

    /* Allocate space to hold dimension IDs */
    dmn_id=(int *)nco_malloc(dmn_nbr*sizeof(int));
    /* Get dimension IDs */
    (void)nco_inq_vardimid(nc_id,var_idx,dmn_id);
    
    /* Is this a record variable? */
    if(rcd_dmn_id != NCO_REC_DMN_UNDEFINED){
      for(dmn_idx=0;dmn_idx<dmn_nbr;dmn_idx++){
	/* Is this the record dimension? */
	if(dmn_id[dmn_idx] == rcd_dmn_id) break; /* ...then search no further */
      } /* end loop over dmn */
      if(dmn_idx < dmn_nbr) is_rec_var=True; /* [flg] Record variable */
    } /* NCO_REC_DMN_UNDEFINED */

    /* Is variable compressed? */
    (void)nco_inq_var_deflate(nc_id,var_idx,NULL,&deflate,NULL);
    if(deflate) is_cmp_var=True; 
    
    /* Is variable checksummed? */
    (void)nco_inq_var_fletcher32(nc_id,var_idx,&chk_typ);
    if(chk_typ != NC_NOCHECKSUM) is_chk_var=True;

    /* Must variable be chunked? */
    if(is_rec_var || is_chk_var || is_cmp_var) must_be_chunked=True; else must_be_chunked=False;

    /* Is variable currently chunked? */
    is_chunked=nco_cnk_dsk_inq(nc_id,var_idx);

    /* Explicitly turn off chunking for arrays that are... */
    if((cnk_plc == nco_cnk_plc_g2d && dmn_nbr < 2) || /* ...much too small... */
       (cnk_plc == nco_cnk_plc_g3d && dmn_nbr < 3) || /* ...too small... */
       (cnk_plc == nco_cnk_plc_uck) || /* ...intentionally unchunked... */
       False){
      /* If variable is chunked */
      if(is_chunked){
	if(must_be_chunked){
	  if(dbg_lvl_get() >= nco_dbg_var) (void)fprintf(stderr,"%s: INFO %s %s must be chunked (record, compressed, or checksummed variable)\n",prg_nm_get(),fnc_nm,var_nm);
	}else{
	  /* Turn off chunking for this variable */
	  if(dbg_lvl_get() >= nco_dbg_var) (void)fprintf(stderr,"%s: INFO %s unchunking %s\n",prg_nm_get(),fnc_nm,var_nm);
	  (void)nco_def_var_chunking(nc_id,var_idx,srg_typ,cnk_sz);
	} /* !must_be_chunked */
      }else{ /* !chunked */
	if(dbg_lvl_get() >= nco_dbg_var) (void)fprintf(stderr,"%s: INFO %s not unchunking %s because it is not chunked\n",prg_nm_get(),fnc_nm,var_nm);
      } /* !chunked */
      /* Free space holding dimension IDs before skipping to next variable */
      dmn_id=(int *)nco_free(dmn_id);
      /* Skip to next variable in loop */
      continue;
    } /* end if */

    /* Variable will definitely be chunked */
    srg_typ=NC_CHUNKED; /* [enm] Storage type */
    if(dbg_lvl_get() >= nco_dbg_var) (void)fprintf(stderr,"%s: INFO %s %schunking %s\n",prg_nm_get(),fnc_nm,(is_chunked ? "re-" : "" ),var_nm);

    /* Allocate space to hold chunksizes */
    cnk_sz=(size_t *)nco_malloc(dmn_nbr*sizeof(size_t));
    
    /* Default "equal" chunksize for each dimension */
    cnk_sz_dfl=cnk_sz_scl;
    if(cnk_map == nco_cnk_map_prd){
      double cnk_sz_prd_dbl; /* [nbr] Chunksize product, double precision */
      double cnk_sz_eql_dbl; /* [nbr] Chunksize equal, double precision */
      double cnk_sz_dfl_dbl; /* [nbr] Chunksize default, double precision */
      cnk_sz_prd_dbl=cnk_sz_scl;
      cnk_sz_eql_dbl=pow(cnk_sz_prd_dbl,1.0/dmn_nbr);
      cnk_sz_dfl_dbl=ceil(cnk_sz_eql_dbl);
      cnk_sz_dfl=(size_t)cnk_sz_dfl_dbl;
    } /* endif map_prd */

    for(dmn_idx=0;dmn_idx<dmn_nbr;dmn_idx++){

      /* Get dimension name and size */
      (void)nco_inq_dim(nc_id,dmn_id[dmn_idx],dmn_nm,&dmn_sz);
      
      /* Is this the record dimension? */
      if(dmn_id[dmn_idx] == rcd_dmn_id){
	/* Does policy specify record dimension treatment? */
	if(cnk_map == nco_cnk_map_rd1){
	  cnk_sz[dmn_idx]=1UL;
	  /* This may still be over-ridden by explicitly specified chunksize */
	  goto cnk_xpl_override;
	} /* !nco_cnk_map_rd1 */
	/* Record dimension size in output file is zero until first write
	   Obtain record dimension size from lmt_all structure */
	if(lmt_all_lst[lmt_idx_rec]->BASIC_DMN){
	  /* When not hyperslabbed, use input record dimension size ... */
	  cnk_sz[dmn_idx]=lmt_all_lst[lmt_idx_rec]->dmn_sz_org;
	}else{ /* !BASIC_DMN */
	  /* ... and when hyperslabbed, use user-specified count */
	  cnk_sz[dmn_idx]=lmt_all_lst[lmt_idx_rec]->dmn_cnt;
	} /* !BASIC_DMN */
      }else{ /* !record dimension */
	/* Set non-record dimensions to default, possibly over-ride later */
	cnk_sz[dmn_idx]=dmn_sz;
	if(dmn_sz == 0L){
	  (void)fprintf(stderr,"%s: ERROR %s reports variable %s has dim_sz == 0L for non-record dimension %s. This should not occur and it will cause chunking to fail...\n",prg_nm_get(),fnc_nm,var_nm,dmn_nm);
	} /* endif err */
      } /* !record dimension */

      /* Propagate scalar chunksize, if specified */
      if(cnk_sz_dfl > 0UL){
	if(dmn_id[dmn_idx] == rcd_dmn_id){
	if(lmt_all_lst[lmt_idx_rec]->BASIC_DMN){
	  /* When not hyperslabbed, use input record dimension size ... */
	  cnk_sz[dmn_idx]=(cnk_sz_dfl <= (size_t)lmt_all_lst[lmt_idx_rec]->dmn_sz_org) ? cnk_sz_dfl : (size_t)lmt_all_lst[lmt_idx_rec]->dmn_sz_org;
	}else{ /* !BASIC_DMN */
	  /* ... and when hyperslabbed, use user-specified count */
	  cnk_sz[dmn_idx]=(cnk_sz_dfl <= (size_t)lmt_all_lst[lmt_idx_rec]->dmn_cnt) ? cnk_sz_dfl : (size_t)lmt_all_lst[lmt_idx_rec]->dmn_cnt;
	} /* !BASIC_DMN */
	}else{ /* !rcd_dmn_id */
	  /* Non-record sizes default to cnk_sz_dfl or to dimension size */
	  cnk_sz[dmn_idx]=(cnk_sz_dfl <= (size_t)dmn_sz) ? cnk_sz_dfl : (size_t)dmn_sz;
	} /* !rcd_dmn_id */
      } /* !cnk_sz_dfl */

      cnk_xpl_override: /* end goto */

      /* Explicit chunk specifications override all else */
      for(cnk_idx=0;cnk_idx<cnk_nbr;cnk_idx++){
	/* Match on name not ID */
	if(!strcmp(cnk[cnk_idx]->nm,dmn_nm)){
	  cnk_sz[dmn_idx]=cnk[cnk_idx]->sz;
	  if(dmn_id[dmn_idx] == rcd_dmn_id){
	    if(lmt_all_lst[lmt_idx_rec]->BASIC_DMN){
	      if(cnk_sz[dmn_idx] > (size_t)lmt_all_lst[lmt_idx_rec]->dmn_sz_org){
		(void)fprintf(stderr,"%s: WARNING %s allowing user-specified record dimension chunksize = %lu for %s to exceed record dimension size in input file = %lu. May fail if output file is not concatenated from multiple inputs.\n",prg_nm_get(),fnc_nm,(unsigned long)cnk[cnk_idx]->sz,dmn_nm,lmt_all_lst[lmt_idx_rec]->dmn_sz_org);
	      } /* endif too big */
	    }else{ /* !BASIC_DMN */
	      if(cnk_sz[dmn_idx] > (size_t)lmt_all_lst[lmt_idx_rec]->dmn_cnt){
		(void)fprintf(stderr,"%s: WARNING %s allowing user-specified record dimension chunksize = %lu for %s to exceed user-specified record dimension hyperslab size in input file = %lu. May fail if output file is not concatenated from multiple inputs.\n",prg_nm_get(),fnc_nm,(unsigned long)cnk[cnk_idx]->sz,dmn_nm,lmt_all_lst[lmt_idx_rec]->dmn_cnt);
	      } /* endif too big */
	    } /* !BASIC_DMN */
	  }else{ /* !rcd_dmn_id */
	    if(cnk_sz[dmn_idx] > (size_t)dmn_sz){
	      /* dmn_sz of record dimension may (will) be zero in output file
		 Non-record dimensions, though, must have cnk_sz <= dmn_sz */
	      (void)fprintf(stderr,"%s: WARNING %s trimming user-specified chunksize = %lu to %s size = %lu\n",prg_nm_get(),fnc_nm,(unsigned long)cnk[cnk_idx]->sz,dmn_nm,dmn_sz);
	      /* Trim else out-of-bounds sizes will fail in HDF library in nc_enddef() */
	      cnk_sz[dmn_idx]=(size_t)dmn_sz;
	    } /* endif */
	  } /* !rcd_dmn_id */
	  break;
	} /* cnk_nm != dmn_nm */
      } /* end loop over cnk */

    } /* end loop over dmn */
    
    if(dbg_lvl_get() >= nco_dbg_scl){
      (void)fprintf(stderr,"idx nm\tdmn_sz\tcnk_sz for %s:\n",var_nm);
      for(dmn_idx=0;dmn_idx<dmn_nbr;dmn_idx++){
	(void)nco_inq_dimlen(nc_id,dmn_id[dmn_idx],&dmn_sz);
	(void)nco_inq_dimname(nc_id,dmn_id[dmn_idx],dmn_nm);
	(void)fprintf(stderr,"%2d %s\t%lu\t%lu\n",dmn_idx,dmn_nm,dmn_sz,(unsigned long)cnk_sz[dmn_idx]);
      } /* end loop over dmn */
    } /* endif dbg */

    /* Turn chunking on for this variable */
    (void)nco_def_var_chunking(nc_id,var_idx,srg_typ,cnk_sz);
    
    /* Free space holding dimension IDs and chunksizes */
    dmn_id=(int *)nco_free(dmn_id);
    cnk_sz=(size_t *)nco_free(cnk_sz);

  } /* end loop over var */
  
  return;
} /* end nco_cnk_sz_set() */