dmn_sct * /* O [sct] Output dimension structure */ nco_dmn_fll /* [fnc] Create and return completed dmn_sct */ (const int nc_id, /* I [id] netCDF input file ID */ const int dmn_id, /* I [id] Dimension ID */ const char * const dmn_nm) /* I [sng] Dimension name */ { /* Purpose: nco_malloc() and return a completed dmn_sct */ dmn_sct *dmn; int rcd=NC_NOERR; /* [rcd] Return code */ int rec_dmn_id; dmn=(dmn_sct *)nco_malloc(sizeof(dmn_sct)); dmn->nm=(char *)strdup(dmn_nm); dmn->nm_fll=NULL; dmn->id=dmn_id; dmn->nc_id=nc_id; dmn->xrf=NULL; dmn->val.vp=NULL; dmn->is_crd_dmn=False; dmn->cid=-1; /* [id] Variable ID of associated coordinate, if any */ (void)nco_inq_dimlen(dmn->nc_id,dmn_id,&dmn->sz); /* Get record dimension ID */ (void)nco_inq(dmn->nc_id,(int *)NULL,(int *)NULL,(int *)NULL,&rec_dmn_id); if(dmn->id == rec_dmn_id){ dmn->is_rec_dmn=True; }else{ dmn->is_rec_dmn=False; } /* end if */ rcd=nco_inq_varid_flg(dmn->nc_id,dmn_nm,&dmn->cid); if(rcd == NC_NOERR){ dmn->is_crd_dmn=True; /* What type is coordinate? */ (void)nco_inq_vartype(dmn->nc_id,dmn->cid,&dmn->type); } /* end if */ dmn->cnk_sz=0L; dmn->cnt=dmn->sz; dmn->srt=0L; dmn->end=dmn->sz-1L; dmn->srd=1L; return dmn; } /* end nco_dmn_fll() */
void nco_att_cpy /* [fnc] Copy attributes from input netCDF file to output netCDF file */ (const int in_id, /* I [id] netCDF input-file ID */ const int out_id, /* I [id] netCDF output-file ID */ const int var_in_id, /* I [id] netCDF input-variable ID */ const int var_out_id, /* I [id] netCDF output-variable ID */ const nco_bool PCK_ATT_CPY) /* I [flg] Copy attributes "scale_factor", "add_offset" */ { /* Purpose: Copy attributes from input netCDF file to output netCDF file If var_in_id == NC_GLOBAL, then copy global attributes Otherwise copy only indicated variable's attributes When PCK_ATT_CPY is false, copy all attributes except "scale_factor", "add_offset" */ char att_nm[NC_MAX_NAME]; char var_nm[NC_MAX_NAME]; int idx; int nbr_att; int rcd; /* [enm] Return code */ if(var_in_id == NC_GLOBAL){ (void)nco_inq_natts(in_id,&nbr_att); }else{ (void)nco_inq_varnatts(in_id,var_in_id,&nbr_att); } /* end else */ /* Jump back to here if current attribute is treated specially */ for(idx=0;idx<nbr_att;idx++){ (void)nco_inq_attname(in_id,var_in_id,idx,att_nm); /* Look for same attribute in output variable in output file */ rcd=nco_inq_att_flg(out_id,var_out_id,att_nm,(nc_type *)NULL,(long *)NULL); /* If instructed not to copy packing attributes... */ if(!PCK_ATT_CPY) /* ...and attribute is "scale_factor" or "add_offset" ... */ if(!strcmp(att_nm,"scale_factor") || !strcmp(att_nm,"add_offset")) /* ...then skip remainder of loop, thereby skipping attribute copy... */ continue; /* Inform user when copy will overwrite an existing attribute */ if(dbg_lvl_get() >= nco_dbg_std){ if(rcd == NC_NOERR){ if(var_out_id == NC_GLOBAL){ (void)fprintf(stderr,"%s: INFO Overwriting global attribute %s\n",prg_nm_get(),att_nm); }else{ (void)nco_inq_varname(out_id,var_out_id,var_nm); (void)fprintf(stderr,"%s: INFO Overwriting attribute %s for output variable %s\n",prg_nm_get(),att_nm,var_nm); } /* end else */ } /* end if */ } /* end if dbg */ if(strcmp(att_nm,nco_mss_val_sng_get())){ /* Copy all attributes except _FillValue with fast library routine */ (void)nco_copy_att(in_id,var_in_id,att_nm,out_id,var_out_id); }else{ /* Convert "_FillValue" attribute to unpacked type then copy Impose NCO convention that _FillValue is same type as variable, whether variable is packed or not */ aed_sct aed; long att_sz; size_t att_lng_in; nc_type att_typ_in; nc_type att_typ_out; ptr_unn mss_tmp; (void)nco_inq_att(in_id,var_in_id,att_nm,&att_typ_in,&att_sz); if(att_sz != 1L){ (void)fprintf(stderr,"%s: ERROR input \"%s\" attribute has %li elements, but nco_att_cpy() only works for size of 1\n",prg_nm_get(),att_nm,att_sz); nco_exit(EXIT_FAILURE); } /* end if */ /* Convert "_FillValue" to unpacked type before copying */ aed.att_nm=att_nm; /* Name of attribute */ if(var_out_id == NC_GLOBAL){ aed.var_nm=NULL; }else{ (void)nco_inq_varname(out_id,var_out_id,var_nm); aed.var_nm=var_nm; /* Name of variable, or NULL for global attribute */ } /* end if */ aed.id=out_id; /* Variable ID or NC_GLOBAL ( = -1) for global attribute */ aed.sz=att_sz; /* Number of elements in attribute */ /* Do not convert global attributes or PCK_ATT_CPY */ if(PCK_ATT_CPY || var_out_id==NC_GLOBAL) att_typ_out=att_typ_in; else (void)nco_inq_vartype(out_id,var_out_id,&att_typ_out); if(att_typ_out==att_typ_in){ aed.type=att_typ_out; /* Type of attribute */ aed.val.vp=(void *)nco_malloc(nco_typ_lng(aed.type)); /* Pointer to attribute value */ (void)nco_get_att(in_id,var_in_id,att_nm,aed.val.vp,att_typ_out); }else{ /* att_typ_out!=att_typ_in */ /* Convert type */ aed.type=att_typ_out; /* Type of attribute */ aed.val.vp=(void *)nco_malloc(nco_typ_lng(aed.type)); /* Pointer to attribute value */ att_lng_in=att_sz*nco_typ_lng(att_typ_in); mss_tmp.vp=(void *)nco_malloc(att_lng_in); (void)nco_get_att(in_id,var_in_id,att_nm,mss_tmp.vp,att_typ_in); (void)nco_val_cnf_typ(att_typ_in,mss_tmp,att_typ_out,aed.val); mss_tmp.vp=nco_free(mss_tmp.vp); } /* att_typ_out!=att_typ_in */ /* Overwrite mode causes problems with netCDF4 and "_FillValue" Use create mode instead */ aed.mode=aed_create; (void)nco_aed_prc(out_id,var_out_id,aed); /* Release temporary memory */ aed.val.vp=nco_free(aed.val.vp); } /* endif copying _FillValue */ } /* end loop over attributes */ } /* end nco_att_cpy() */