- Timestamp:
- 12/01/14 19:00:32 (9 years ago)
- Location:
- XIOS/trunk/src/output
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
XIOS/trunk/src/output/netCdfInterface.cpp
r517 r525 8 8 */ 9 9 10 #include "netCdfInterface.hpp" 11 #include "netCdfException.hpp" 12 13 namespace xios 14 { 15 /*! 16 This function creates a new netcdf file and return its id 17 \param [in] fileName Name of the file 18 \param [in] cMode create mode 19 \param [in/out] ncId id of the created file 20 \return Status code 21 */ 22 int CNetCdfInterface::create(const StdString& fileName, int cMode, int& ncId) 23 { 24 int status = nc_create((fileName.c_str()), cMode, &ncId); 25 if (NC_NOERR != status) 26 { 27 StdString errormsg(nc_strerror(status)); 28 StdStringStream sstr; 29 sstr << "Error in calling function : nc_create((fileName.c_str()), cMode, &ncId) " << std::endl 30 << errormsg << std::endl 31 << "Unable to create file, given its name : " << fileName 32 << "and its creation mode " << creationMode2String(cMode) << std::endl; 33 StdString e = sstr.str(); 34 throw CNetCdfException(e); 35 } 36 37 return status; 38 } 39 40 /*! 41 This function creates a new netcdf file on parallel file system 42 \param [in] fileName Name of the file 43 \param [in] cMode create mode 44 \param [in] comm MPI communicator 45 \param [in] info MPI information 46 \param [in/out] ncId id of the created file 47 \return Status code 48 */ 49 int CNetCdfInterface::createPar(const StdString& fileName, int cMode, MPI_Comm comm, MPI_Info info, int& ncId) 50 { 51 int status = xios::nc_create_par((fileName.c_str()), cMode, comm, info, &ncId); 52 if (NC_NOERR != status) 53 { 54 StdString errormsg(nc_strerror(status)); 55 StdStringStream sstr; 56 sstr << "Error in calling function : nc_create_par((fileName.c_str()), cMode, comm, info, &ncId) " << std::endl 57 << errormsg << std::endl 58 << "Unable to create file on parallel filesys, given its name : " << std::endl 59 << "and its creation mode " << creationMode2String(cMode) << std::endl; 60 StdString e = sstr.str(); 61 throw CNetCdfException(e); 62 } 63 64 return status; 65 } 66 67 /*! 68 This function opens a netcdf file, given its name and open mode, return its id 69 \param [in] fileName Name of the file 70 \param [in] oMode open mode 71 \param [in/out] ncId id of the opening file 72 \return Status code 73 */ 74 int CNetCdfInterface::open(const StdString& fileName, int oMode, int& ncId) 75 { 76 int status = nc_open((fileName.c_str()), oMode, &ncId); 77 if (NC_NOERR != status) 78 { 79 StdString errormsg(nc_strerror(status)); 80 StdStringStream sstr; 81 sstr << "Error in calling function : nc_open((fileName.c_str()), oMode, &ncId) "<< std::endl 82 << errormsg << std::endl 83 << "Unable to open file, given its name : " << fileName 84 << "and its open mode " << openMode2String(oMode) << std::endl; 85 StdString e = sstr.str(); 86 throw CNetCdfException(e); 87 } 88 89 return status; 90 } 91 92 93 /*! 94 This function opens a new netcdf file on parallel file system 95 \param [in] fileName Name of the file 96 \param [in] oMode open mode 97 \param [in] comm MPI communicator 98 \param [in] info MPI information 99 \param [in/out] ncId id of the opened file 100 \return Status code 101 */ 102 int CNetCdfInterface::openPar(const StdString& fileName, int oMode, MPI_Comm comm, MPI_Info info, int& ncId) 103 { 104 int status = xios::nc_open_par((fileName.c_str()), oMode, comm, info, &ncId); 105 if (NC_NOERR != status) 106 { 107 StdString errormsg(nc_strerror(status)); 108 StdStringStream sstr; 109 sstr << "Error in calling function " << "nc_open_par((fileName.c_str()), oMode, comm, info, &ncId) " << std::endl 110 << errormsg << std::endl 111 << "Unable to open file on parallel filesys, given its name : " << fileName 112 << "and its open mode " << openMode2String(oMode) << std::endl; 113 StdString e = sstr.str(); 114 throw CNetCdfException(e); 115 } 116 117 return status; 118 } 119 120 /*! 121 This function closes a netcdf file, given its id 122 \param [in] ncId id of the opening netcdf file 123 \return Status code 124 */ 125 int CNetCdfInterface::close(int ncId) 126 { 127 int status = nc_close(ncId); 128 if (NC_NOERR != status) 129 { 130 StdString errormsg(nc_strerror(status)); 131 StdStringStream sstr; 132 sstr << "Error in calling function " << "nc_close(ncId)" << std::endl 133 << errormsg << std::endl 134 << "Unable to close file, given its id : " << ncId << std::endl; 135 StdString e = sstr.str(); 136 throw CNetCdfException(e); 137 } 138 139 return status; 140 } 141 142 /*! 143 This function put a netcdf file into define mode, given its id 144 \param [in] ncId id of the opening netcdf file to be put into define mode 145 \return Status code 146 */ 147 int CNetCdfInterface::reDef(int ncId) 148 { 149 int status = nc_redef(ncId); 150 if (NC_NOERR != status) 151 { 152 StdString errormsg(nc_strerror(status)); 153 StdStringStream sstr; 154 sstr << "Error in calling function " << "nc_redef(ncId)" << std::endl 155 << errormsg << std::endl 156 << "Unable to put this file into define mode given its id : " << ncId << std::endl; 157 StdString e = sstr.str(); 158 throw CNetCdfException(e); 159 } 160 161 return status; 162 } 163 164 /*! 165 This function ends a netcdf file define mode, given its id 166 \param [in] ncId id of the opening netcdf file to be put into define mode 167 \return Status code 168 */ 169 int CNetCdfInterface::endDef(int ncId) 170 { 171 int status = nc_enddef(ncId); 172 if (NC_NOERR != status) 173 { 174 StdString errormsg(nc_strerror(status)); 175 StdStringStream sstr; 176 177 sstr << "Error in calling function " << "nc_enddef(ncId)" << std::endl 178 << errormsg << std::endl 179 << "Unable to end define mode of this file, given its id : " << ncId << std::endl; 180 StdString e = sstr.str(); 181 throw CNetCdfException(e); 182 } 183 184 return status; 185 } 186 187 /*! 188 This function makes a request to netcdf with ncid and group name then return ncid of the named group 189 \param [in] ncid Groupd id (or File Id) 190 \param [in] grpName Name of the desired group (or file) 191 \param [in/out] grpId Group id if the group is found 192 \return Status code 193 */ 194 int CNetCdfInterface::inqNcId(int ncid, const StdString& grpName, int& grpId) 195 { 196 int status = nc_inq_ncid(ncid, (grpName.c_str()), &grpId); 197 if (NC_NOERR != status) 198 { 199 StdString errormsg(nc_strerror(status)); 200 StdStringStream sstr; 201 202 sstr << "Error in calling function " << "nc_inq_ncid(ncid, (grpName.c_str()), &grpId)" << std::endl 203 << errormsg << std::endl 204 << "Unable to get id of a group (File), given its name : " << grpName << std::endl; 205 StdString e = sstr.str(); 206 throw CNetCdfException(e); 207 } 208 209 return status; 210 } 211 212 213 /*! 214 This function makes a request to netcdf with ncid and variable name then return ncid of the named variable 215 \param [in] ncid Groupd id (or File Id) 216 \param [in] varName Name of the desired variable 217 \param [in/out] varId Variable id if this variable is found 218 \return Status code 219 */ 220 int CNetCdfInterface::inqVarId(int ncid,const StdString& varName, int& varId) 221 { 222 int status = nc_inq_varid(ncid, (varName.c_str()), &varId); 223 if (NC_NOERR != status) 224 { 225 StdString errormsg(nc_strerror(status)); 226 StdStringStream sstr; 227 228 sstr << "Error in calling function : nc_inq_varid(ncid, (varName.c_str()), &varId)" << std::endl 229 << (errormsg) << std::endl 230 << "Unable to get id of variable with name : " << varName << std::endl; 231 StdString e = sstr.str(); 232 throw CNetCdfException(e); 233 } 234 235 return status; 236 } 237 238 /*! 239 This function makes a request to netcdf with a netCdf dimension name then return ncid of the named dimension 240 \param [in] ncid Groupd id (or File Id) 241 \param [in] dimName Name of the desired dimension 242 \param [in/out] dimId Dimension id if this dimension is found 243 \return Status code 244 */ 245 int CNetCdfInterface::inqDimId(int ncid,const StdString& dimName, int& dimId) 246 { 247 int status = nc_inq_dimid(ncid, (dimName.c_str()), &dimId); 248 if (NC_NOERR != status) 249 { 250 StdString errormsg(nc_strerror(status)); 251 StdStringStream sstr; 252 253 sstr << "Error in calling function " << "nc_inq_dimid(ncid, (dimName.c_str()), &dimId)" << std::endl 254 << errormsg << std::endl 255 << "Unable to get id of dimension, given its name : " << dimName << std::endl; 256 StdString e = sstr.str(); 257 throw CNetCdfException(e); 258 } 259 260 return status; 261 } 262 263 /*! 264 This function makes a request to netcdf with a netCdf dimension name then return ncid of the named dimension 265 \param [in] ncid Groupd id (or File Id) 266 \param [in/out] dimId Dimension id if this dimension is found 267 \return Status code 268 */ 269 int CNetCdfInterface::inqUnLimDim(int ncid, int& dimId) 270 { 271 int status = nc_inq_unlimdim(ncid, &dimId); 272 if (NC_NOERR != status) 273 { 274 StdString errormsg(nc_strerror(status)); 275 StdStringStream sstr; 276 277 sstr << "Error in calling function " << "nc_inq_dimid" << std::endl 278 << errormsg << std::endl 279 << "Unable to get id of unlimited dimension " << std::endl; 280 StdString e = sstr.str(); 281 throw CNetCdfException(e); 282 } 283 284 return status; 285 } 286 287 /*! 288 This function makes a request to netcdf, returns name of a dimension, given its id 289 \param [in] ncid Groupd id (or File Id) 290 \param [in] dimId Id of desired dimension 291 \param [in/out] dimName Name of desired dimension 292 \return Status code 293 */ 294 int CNetCdfInterface::inqDimName(int ncid, int dimId, StdString& dimName) 295 { 296 char fullNameIn[NC_MAX_NAME +1]; 297 int status = nc_inq_dimname(ncid, dimId, fullNameIn); 298 if (NC_NOERR != status) 299 { 300 StdString errormsg(nc_strerror(status)); 301 StdStringStream sstr; 302 303 sstr << "Error in calling function " << "nc_inq_dimname(ncid, dimId, fullNameIn)" << std::endl 304 << errormsg << std::endl 305 << "Unable to get dimension name from its id : " << dimId << std::endl; 306 StdString e = sstr.str(); 307 throw CNetCdfException(e); 308 } 309 dimName = StdString(fullNameIn); 310 return status; 311 } 312 313 /*! 314 This function makes a request to netcdf, returns length of a dimension, given its id 315 \param [in] ncid Groupd id (or File Id) 316 \param [in] dimId Id of desired dimension 317 \param [in/out] dimLen Length of desired dimension 318 \return Status code 319 */ 320 int CNetCdfInterface::inqDimLen(int ncid, int dimId, StdSize& dimLen) 321 { 322 int status = nc_inq_dimlen(ncid, dimId, &dimLen); 323 if (NC_NOERR != status) 324 { 325 StdString errormsg(nc_strerror(status)); 326 StdStringStream sstr; 327 328 sstr << "Error in calling function " << "nc_inq_dimlen(ncid, dimId, &dimLen)" << std::endl 329 << errormsg << std::endl 330 << "Unable to get dimension length from its id: " << dimId << std::endl; 331 StdString e = sstr.str(); 332 throw CNetCdfException(e); 333 } 334 335 return status; 336 } 337 338 /*! 339 This function makes a request to netcdf, returns number of dimensions of a variable, given its id 340 \param [in] ncid Groupd id (or File Id) 341 \param [in] varId Id of variable 342 \param [in/out] ndims number of dimension of the variable 343 \return Status code 344 */ 345 int CNetCdfInterface::inqVarNDims(int ncid, int varId, int& nDims) 346 { 347 int status = nc_inq_varndims(ncid, varId, &nDims); 348 if (NC_NOERR != status) 349 { 350 StdString errormsg(nc_strerror(status)); 351 StdStringStream sstr; 352 353 sstr << "Error in calling function " << "nc_inq_varndims(ncid, varId, &nDims)" << std::endl 354 << errormsg << std::endl 355 << "Unable to get the number of dimension of variable with Id : " << varId << std::endl; 356 StdString e = sstr.str(); 357 throw CNetCdfException(e); 358 } 359 360 return status; 361 } 362 363 /*! 364 This function makes a request to netcdf, returns a list of dimension ID describing the shape of the variable, given its id 365 \param [in] ncid Groupd id (or File Id) 366 \param [in] varId Id of variable 367 \param [in/out] dimIds list of dimension of the variable 368 \return Status code 369 */ 370 int CNetCdfInterface::inqVarDimId(int ncid, int varId, int* dimIds) 371 { 372 int status = nc_inq_vardimid(ncid, varId, dimIds); 373 if (NC_NOERR != status) 374 { 375 StdString errormsg(nc_strerror(status)); 376 StdStringStream sstr; 377 378 sstr << "Error in calling function " << "nc_inq_vardimid(ncid, varId, dimIds)" << std::endl 379 << errormsg << std::endl 380 << "Unable to get list of dimension id of the variable with id " << varId << std::endl; 381 StdString e = sstr.str(); 382 throw CNetCdfException(e); 383 } 384 385 return status; 386 } 387 388 /*! 389 This function makes a request to netcdf, to find all dimension in a group 390 \param [in] ncid Groupd id (or File Id) 391 \param [in/out] nDims number of list of dimension 392 \param [in/out] dimIds list of dimension in a group or any of its parent 393 \param [in] includeParents number of parents 394 \return Status code 395 */ 396 int CNetCdfInterface::inqDimIds(int ncid, int& nDims, int* dimIds, int includeParents) 397 { 398 int status = nc_inq_dimids(ncid, &nDims, dimIds, includeParents); 399 if (NC_NOERR != status) 400 { 401 StdString errormsg(nc_strerror(status)); 402 StdStringStream sstr; 403 404 sstr << "Error in calling function " << "nc_inq_dimids(ncid, &nDims, dimIds, includeParents)" << std::endl; 405 sstr << errormsg << std::endl; 406 sstr << "Unable to retrieve number of dimension in the group with id : " << ncid << std::endl; 407 sstr << "With number of Parents " << includeParents << std::endl; 408 StdString e = sstr.str(); 409 throw CNetCdfException(e); 410 } 411 412 return status; 413 } 414 415 /*! 416 This function makes a request to netcdf with a id of a prent groupd and then return id of the created group, given its name 417 \param [in] parentNcid Id of parent groupd(or File Id) 418 \param [in] grpName Name of the desired group 419 \param [in/out] grpId Group id if this group is created sucessfully 420 \return Status code 421 */ 422 int CNetCdfInterface::defGrp(int parentNcid, const StdString& grpName, int& grpId) 423 { 424 int status = nc_def_grp(parentNcid, (grpName.c_str()), &grpId); 425 if (NC_NOERR != status) 426 { 427 StdString errormsg(nc_strerror(status)); 428 StdStringStream sstr; 429 430 sstr << "Error in calling function " << "nc_def_grp(parentNcid, (grpName.c_str()), &grpId)" << std::endl; 431 sstr << errormsg << std::endl; 432 sstr << "Unable to create group Id, given its name : " << grpName << std::endl; 433 StdString e = sstr.str(); 434 throw CNetCdfException(e); 435 } 436 437 return status; 438 } 439 440 /*! 441 This function makes a request to netcdf, add a new dimension to an open netcdf in define mode 442 \param [in] ncid Id of groupd(or File Id) 443 \param [in] dimName Name of the desired dimension 444 \param [in/out] grpId Group id if this group is created sucessfully 445 \return Status code 446 */ 447 int CNetCdfInterface::defDim(int ncid, const StdString& dimName, StdSize dimLen, int& dimId) 448 { 449 int status = nc_def_dim(ncid, (dimName.c_str()), dimLen, &dimId); 450 if (NC_NOERR != status) 451 { 452 StdString errormsg(nc_strerror(status)); 453 StdStringStream sstr; 454 455 sstr << "Error in calling function " << "nc_def_dim(ncid, (dimName.c_str()), dimLen, &dimId)" << std::endl; 456 sstr << errormsg << std::endl; 457 sstr << "Unable to create dimension with name : " << dimName 458 << " and with length " << dimLen << std::endl; 459 StdString e = sstr.str(); 460 throw CNetCdfException(e); 461 } 462 463 return status; 464 } 465 466 /*! 467 This function makes a request to netcdf with its id, to add a new variable to an open netCdf in define mode, 468 return a variable id, given its name, type, the number of dimensions and list of dimension id 469 \param [in] ncid Id of groupd(or File Id) 470 \param [in] varName Name of the desired dimension 471 \param [in] xtypes One of the set of predefined netCDF data types 472 \param [in] nDims Number of dimension for the variable 473 \param [in] dimIds List of ndims dimension ids corresponding to the variable dimensions 474 \param [in/out] varId Variable id if it is added sucessfully 475 \return Status code 476 */ 477 int CNetCdfInterface::defVar(int ncid,const StdString& varName, nc_type xtype, 478 int nDims, const int dimIds[], int& varId) 479 { 480 int status = nc_def_var(ncid, (varName.c_str()), xtype, nDims, dimIds, &varId); 481 if (NC_NOERR != status) 482 { 483 StdString errormsg(nc_strerror(status)); 484 StdStringStream sstr; 485 486 sstr << "Error in calling function " << " nc_def_var(ncid, (varName.c_str()), xtype, nDims, dimIds, &varId)" << std::endl; 487 sstr << errormsg << std::endl; 488 sstr << "Unable to add a new variable with name : " << varName 489 << " with type " << xtype 490 << " and number of dimension " << nDims << std::endl; 491 StdString e = sstr.str(); 492 throw CNetCdfException(e); 493 } 494 495 return status; 496 } 497 498 /*! 499 This function makes a request to netcdf with a ncid, to set the chunking size of a variable, 500 given variable id and type of storage 501 \param [in] ncid Id groupd(or File Id) 502 \param [in] varId Id of the variable 503 \param [in] storage Type of storage (It can be : NC_CONTIGUOUS, NC_CHUNKED) 504 \param [in/out] chunkSize array list of chunk sizes 505 \return Status code 506 */ 507 int CNetCdfInterface::defVarChunking(int ncid, int varId, int storage, StdSize chunkSize[]) 508 { 509 int status = nc_def_var_chunking(ncid, varId, storage, chunkSize); 510 if (NC_NOERR != status) 511 { 512 StdString errormsg(nc_strerror(status)); 513 StdStringStream sstr; 514 515 sstr << "Error in calling function " << "nc_def_var_chunking(ncid, varId, storage, chunkSize)" << std::endl; 516 sstr << errormsg << std::endl; 517 sstr << "Unable to set chunk size of the variable with id : " << varId 518 << " and storage type " << storage << std::endl; 519 StdString e = sstr.str(); 520 throw CNetCdfException(e); 521 } 522 523 return status; 524 } 525 526 /*! 527 Set or unset the fill mode for a NetCDF file specified by its file id. 528 \param [in] ncid File id 529 \param [in] fill Define whether the fill mode should be enabled or not 530 \return Status code 531 */ 532 int CNetCdfInterface::setFill(int ncid, bool fill) 533 { 534 int old_fill_mode; 535 int status = nc_set_fill(ncid, fill ? NC_FILL : NC_NOFILL, &old_fill_mode); 536 if (NC_NOERR != status) 537 { 538 StdString errormsg(nc_strerror(status)); 539 StdStringStream sstr; 540 541 sstr << "Error when calling function nc_set_fill(ncid, fill ? NC_FILL : NC_NOFILL, &old_fill_mode)" << std::endl; 542 sstr << errormsg << std::endl; 543 sstr << "Unable to set the fill mode to : " << (fill ? "NC_FILL" : "NC_NOFILL") << std::endl; 544 StdString e = sstr.str(); 545 throw CNetCdfException(e); 546 } 547 548 return status; 549 } 550 551 /*! 552 This function makes a request to netcdf with a ncid, to set the fill parameters for a variable, 553 given variable id and type of fill 554 \param [in] ncid Id groupd(or File Id) 555 \param [in] varId Id of the variable 556 \param [in] noFill turn on/off nofill mode on a variable 557 \param [in/out] fillValue 558 \return Status code 559 */ 560 int CNetCdfInterface::defVarFill(int ncid, int varId, int noFill, void* fillValue) 561 { 562 int status = nc_def_var_fill(ncid, varId, noFill, fillValue); 563 if (NC_NOERR != status) 564 { 565 StdString errormsg(nc_strerror(status)); 566 StdStringStream sstr; 567 568 sstr << "Error in calling function " << "nc_def_var_fill(ncid, varId, noFill, fillValue)" << std::endl; 569 sstr << errormsg << std::endl; 570 sstr << "Unable to set fill parameters of the variable with id : " << varId 571 << " and fill option " << noFill << std::endl; 572 StdString e = sstr.str(); 573 throw CNetCdfException(e); 574 } 575 576 return status; 577 } 578 579 /*! 580 This function makes a request to netcdf with a ncid, to change the way read/write operations are performed 581 collectively or independently on the variable. 582 \param [in] ncid Id groupd(or File Id) 583 \param [in] varId Id of the variable 584 \param [in] noFill turn on/off nofill mode on a variable 585 \param [in/out] fillValue 586 \return Status code 587 */ 588 int CNetCdfInterface::varParAccess(int ncid, int varId, int access) 589 { 590 int status = nc_var_par_access(ncid, varId, access); 591 if (NC_NOERR != status) 592 { 593 StdString errormsg(nc_strerror(status)); 594 StdStringStream sstr; 595 596 sstr << "Error in calling function " << "nc_var_par_access(ncid, varId, access)" << std::endl; 597 sstr << errormsg << std::endl; 598 sstr << "Unable to change read/write option of the variable with id : " << varId << std::endl; 599 StdString e = sstr.str(); 600 throw CNetCdfException(e); 601 } 602 603 return status; 604 } 605 606 /*! 607 This function makes a synchronisation of the disk copy of a netCDF dataset. 608 \param [in] ncid Id groupd(or File Id) 609 \return Status code 610 */ 611 int CNetCdfInterface::sync(int ncid) 612 { 613 int status = nc_sync(ncid); 614 if (NC_NOERR != status) 615 { 616 StdString errormsg(nc_strerror(status)); 617 StdStringStream sstr; 618 619 sstr << "Error in calling function " << "nc_sync(ncid)" << std::endl; 620 sstr << errormsg << std::endl; 621 sstr << "Unable to make a synchronization of a netCDF file with id : " << ncid << std::endl; 622 StdString e = sstr.str(); 623 throw CNetCdfException(e); 624 } 625 626 return status; 627 } 628 629 /*! 630 This function makes a request to netcdf with its id, to add or change a variable attribute or gloabl attribute, 631 given its name, type, number of values provided for attribute 632 \param [in] ncid Id of groupd(or File Id) 633 \param [in] varId Id of the variable 634 \param [in] attrName Name of the attribute 635 \param [in] xtypes One of the set of predefined netCDF data types 636 \param [in] numVal Number of values 637 \param [in] op Array of values provided for attribute 638 \return Status code 639 */ 640 int CNetCdfInterface::putAtt(int ncid, int varId, const StdString& attrName, nc_type xtype, 641 StdSize numVal, const void* op) 642 { 643 int status = nc_put_att(ncid, varId, (attrName.c_str()), xtype, numVal, op); 644 if (NC_NOERR != status) 645 { 646 StdString errormsg(nc_strerror(status)); 647 StdStringStream sstr; 648 649 sstr << "Error in calling function " << "nc_put_att(ncid, varId, (attrName.c_str()), xtype, numVal, op)" << std::endl; 650 sstr << errormsg << std::endl; 651 sstr << "Unable to set attribute " << attrName << " for a variable with id : " << varId 652 << " with number of attribute " << numVal 653 << " with type " << xtype << std::endl; 654 StdString e = sstr.str(); 655 throw CNetCdfException(e); 656 } 657 658 return status; 659 } 660 661 // Some specilization of putAttributeType 662 template<> 663 int CNetCdfInterface::ncPutAttType(int ncid, int varid, const char* attrName, 664 StdSize numVal, const double* op) 665 { 666 return (nc_put_att_double(ncid, varid, attrName, NC_DOUBLE, numVal, op)); 667 } 668 669 template<> 670 int CNetCdfInterface::ncPutAttType(int ncid, int varid, const char* attrName, 671 StdSize numVal, const float* op) 672 { 673 return (nc_put_att_float(ncid, varid, attrName, NC_FLOAT, numVal, op)); 674 } 675 676 template<> 677 int CNetCdfInterface::ncPutAttType(int ncid, int varid, const char* attrName, 678 StdSize numVal, const int* op) 679 { 680 return (nc_put_att_int(ncid, varid, attrName, NC_INT, numVal, op)); 681 } 682 683 template<> 684 int CNetCdfInterface::ncPutAttType(int ncid, int varid, const char* attrName, 685 StdSize numVal, const long* op) 686 { 687 return (nc_put_att_long(ncid, varid, attrName, NC_LONG, numVal, op)); 688 } 689 690 template<> 691 int CNetCdfInterface::ncPutAttType(int ncid, int varid, const char* attrName, 692 StdSize numVal, const short* op) 693 { 694 return (nc_put_att_short(ncid, varid, attrName, NC_SHORT, numVal, op)); 695 } 696 697 698 // Some specilization of putVariableType 699 template<> 700 int CNetCdfInterface::ncPutVaraType(int ncid, int varid, const StdSize* start, const StdSize* count, const double* op) 701 { 702 return (nc_put_vara_double(ncid, varid, start, count, op)); 703 } 704 705 template<> 706 int CNetCdfInterface::ncPutVaraType(int ncid, int varid, const StdSize* start, const StdSize* count, const float* op) 707 { 708 return (nc_put_vara_float(ncid, varid, start, count, op)); 709 } 710 711 template<> 712 int CNetCdfInterface::ncPutVaraType(int ncid, int varid, const StdSize* start, const StdSize* count, const int* op) 713 { 714 return (nc_put_vara_int(ncid, varid, start, count, op)); 715 } 716 717 /*! 718 This function verifies an existence of a variable by using its name. 719 Be careful, althoug false means variable doens't exist, it could show that netCDF file doesn't either 720 \param [in] ncid Id of groupd(or File Id) 721 \param [in] attrName Name of the variable 722 \return Existence of variable 723 */ 724 bool CNetCdfInterface::isVarExisted(int ncId, const StdString& varName) 725 { 726 int varId = 0; 727 return (NC_NOERR == (nc_inq_varid(ncId, varName.c_str(), &varId))); 728 } 729 730 StdString CNetCdfInterface::openMode2String(int oMode) 731 { 732 StdString modeMes; 733 switch (oMode) 734 { 735 case NC_NOWRITE: 736 modeMes = StdString("NC_NOWRITE : Opening netCDF file with read-only access with buffering and caching access"); 737 break; 738 case NC_SHARE: 739 modeMes = StdString("NC_SHARE : Several processes can read the file concurrently"); 740 break; 741 case NC_WRITE: 742 modeMes = StdString("NC_WRITE : NetCDF file is readable and writable"); 743 break; 744 default: 745 modeMes = StdString("In the composed opening mode"); 746 break; 747 return modeMes; 748 } 749 } 750 751 StdString CNetCdfInterface::creationMode2String(int cMode) 752 { 753 StdString modeMes; 754 switch (cMode) 755 { 756 case NC_NOCLOBBER: 757 modeMes = StdString("NC_NOCLOBBER : Not overwrite an exisiting netCDF file "); 758 break; 759 case NC_SHARE: 760 modeMes = StdString("NC_SHARE : Several processes can read from and write into the file concurrently"); 761 break; 762 case NC_64BIT_OFFSET: 763 modeMes = StdString("NC_64BIT_OFFSET : NetCDF file is 64-bit offset"); 764 break; 765 case NC_NETCDF4: 766 modeMes = StdString("NC_NETCDF4 : NetCDF file is HDF5/NetCDF-4"); 767 break; 768 case NC_CLASSIC_MODEL: 769 modeMes = StdString("NC_CLASSIC_MODEL : NetCDF file is classical model"); 770 break; 771 default: 772 modeMes = StdString("In the composed creation mode"); 773 break; 774 return modeMes; 775 } 776 } 777 10 #include "netCdfInterface.hpp" 11 #include "netCdfException.hpp" 12 13 namespace xios 14 { 15 /*! 16 This function creates a new netcdf file and return its id 17 \param [in] fileName Name of the file 18 \param [in] cMode create mode 19 \param [in/out] ncId id of the created file 20 \return Status code 21 */ 22 int CNetCdfInterface::create(const StdString& fileName, int cMode, int& ncId) 23 { 24 int status = nc_create((fileName.c_str()), cMode, &ncId); 25 if (NC_NOERR != status) 26 { 27 StdString errormsg(nc_strerror(status)); 28 StdStringStream sstr; 29 sstr << "Error in calling function : nc_create((fileName.c_str()), cMode, &ncId) " << std::endl 30 << errormsg << std::endl 31 << "Unable to create file, given its name : " << fileName 32 << "and its creation mode " << creationMode2String(cMode) << std::endl; 33 StdString e = sstr.str(); 34 throw CNetCdfException(e); 35 } 36 37 return status; 38 } 39 40 /*! 41 This function creates a new netcdf file on parallel file system 42 \param [in] fileName Name of the file 43 \param [in] cMode create mode 44 \param [in] comm MPI communicator 45 \param [in] info MPI information 46 \param [in/out] ncId id of the created file 47 \return Status code 48 */ 49 int CNetCdfInterface::createPar(const StdString& fileName, int cMode, MPI_Comm comm, MPI_Info info, int& ncId) 50 { 51 int status = xios::nc_create_par((fileName.c_str()), cMode, comm, info, &ncId); 52 if (NC_NOERR != status) 53 { 54 StdString errormsg(nc_strerror(status)); 55 StdStringStream sstr; 56 sstr << "Error in calling function : nc_create_par((fileName.c_str()), cMode, comm, info, &ncId) " << std::endl 57 << errormsg << std::endl 58 << "Unable to create file on parallel filesys, given its name : " << std::endl 59 << "and its creation mode " << creationMode2String(cMode) << std::endl; 60 StdString e = sstr.str(); 61 throw CNetCdfException(e); 62 } 63 64 return status; 65 } 66 67 /*! 68 This function opens a netcdf file, given its name and open mode, return its id 69 \param [in] fileName Name of the file 70 \param [in] oMode open mode 71 \param [in/out] ncId id of the opening file 72 \return Status code 73 */ 74 int CNetCdfInterface::open(const StdString& fileName, int oMode, int& ncId) 75 { 76 int status = nc_open((fileName.c_str()), oMode, &ncId); 77 if (NC_NOERR != status) 78 { 79 StdString errormsg(nc_strerror(status)); 80 StdStringStream sstr; 81 sstr << "Error in calling function : nc_open((fileName.c_str()), oMode, &ncId) "<< std::endl 82 << errormsg << std::endl 83 << "Unable to open file, given its name : " << fileName 84 << "and its open mode " << openMode2String(oMode) << std::endl; 85 StdString e = sstr.str(); 86 throw CNetCdfException(e); 87 } 88 89 return status; 90 } 91 92 93 /*! 94 This function opens a new netcdf file on parallel file system 95 \param [in] fileName Name of the file 96 \param [in] oMode open mode 97 \param [in] comm MPI communicator 98 \param [in] info MPI information 99 \param [in/out] ncId id of the opened file 100 \return Status code 101 */ 102 int CNetCdfInterface::openPar(const StdString& fileName, int oMode, MPI_Comm comm, MPI_Info info, int& ncId) 103 { 104 int status = xios::nc_open_par((fileName.c_str()), oMode, comm, info, &ncId); 105 if (NC_NOERR != status) 106 { 107 StdString errormsg(nc_strerror(status)); 108 StdStringStream sstr; 109 sstr << "Error in calling function " << "nc_open_par((fileName.c_str()), oMode, comm, info, &ncId) " << std::endl 110 << errormsg << std::endl 111 << "Unable to open file on parallel filesys, given its name : " << fileName 112 << "and its open mode " << openMode2String(oMode) << std::endl; 113 StdString e = sstr.str(); 114 throw CNetCdfException(e); 115 } 116 117 return status; 118 } 119 120 /*! 121 This function closes a netcdf file, given its id 122 \param [in] ncId id of the opening netcdf file 123 \return Status code 124 */ 125 int CNetCdfInterface::close(int ncId) 126 { 127 int status = nc_close(ncId); 128 if (NC_NOERR != status) 129 { 130 StdString errormsg(nc_strerror(status)); 131 StdStringStream sstr; 132 sstr << "Error in calling function " << "nc_close(ncId)" << std::endl 133 << errormsg << std::endl 134 << "Unable to close file, given its id : " << ncId << std::endl; 135 StdString e = sstr.str(); 136 throw CNetCdfException(e); 137 } 138 139 return status; 140 } 141 142 /*! 143 This function put a netcdf file into define mode, given its id 144 \param [in] ncId id of the opening netcdf file to be put into define mode 145 \return Status code 146 */ 147 int CNetCdfInterface::reDef(int ncId) 148 { 149 int status = nc_redef(ncId); 150 if (NC_NOERR != status) 151 { 152 StdString errormsg(nc_strerror(status)); 153 StdStringStream sstr; 154 sstr << "Error in calling function " << "nc_redef(ncId)" << std::endl 155 << errormsg << std::endl 156 << "Unable to put this file into define mode given its id : " << ncId << std::endl; 157 StdString e = sstr.str(); 158 throw CNetCdfException(e); 159 } 160 161 return status; 162 } 163 164 /*! 165 This function ends a netcdf file define mode, given its id 166 \param [in] ncId id of the opening netcdf file to be put into define mode 167 \return Status code 168 */ 169 int CNetCdfInterface::endDef(int ncId) 170 { 171 int status = nc_enddef(ncId); 172 if (NC_NOERR != status) 173 { 174 StdString errormsg(nc_strerror(status)); 175 StdStringStream sstr; 176 177 sstr << "Error in calling function " << "nc_enddef(ncId)" << std::endl 178 << errormsg << std::endl 179 << "Unable to end define mode of this file, given its id : " << ncId << std::endl; 180 StdString e = sstr.str(); 181 throw CNetCdfException(e); 182 } 183 184 return status; 185 } 186 187 /*! 188 This function makes a request to netcdf with ncid and group name then return ncid of the named group 189 \param [in] ncid Groupd id (or File Id) 190 \param [in] grpName Name of the desired group (or file) 191 \param [in/out] grpId Group id if the group is found 192 \return Status code 193 */ 194 int CNetCdfInterface::inqNcId(int ncid, const StdString& grpName, int& grpId) 195 { 196 int status = nc_inq_ncid(ncid, (grpName.c_str()), &grpId); 197 if (NC_NOERR != status) 198 { 199 StdString errormsg(nc_strerror(status)); 200 StdStringStream sstr; 201 202 sstr << "Error in calling function " << "nc_inq_ncid(ncid, (grpName.c_str()), &grpId)" << std::endl 203 << errormsg << std::endl 204 << "Unable to get id of a group (File), given its name : " << grpName << std::endl; 205 StdString e = sstr.str(); 206 throw CNetCdfException(e); 207 } 208 209 return status; 210 } 211 212 213 /*! 214 This function makes a request to netcdf with ncid and variable name then return ncid of the named variable 215 \param [in] ncid Groupd id (or File Id) 216 \param [in] varName Name of the desired variable 217 \param [in/out] varId Variable id if this variable is found 218 \return Status code 219 */ 220 int CNetCdfInterface::inqVarId(int ncid,const StdString& varName, int& varId) 221 { 222 int status = nc_inq_varid(ncid, (varName.c_str()), &varId); 223 if (NC_NOERR != status) 224 { 225 StdString errormsg(nc_strerror(status)); 226 StdStringStream sstr; 227 228 sstr << "Error in calling function : nc_inq_varid(ncid, (varName.c_str()), &varId)" << std::endl 229 << (errormsg) << std::endl 230 << "Unable to get id of variable with name : " << varName << std::endl; 231 StdString e = sstr.str(); 232 throw CNetCdfException(e); 233 } 234 235 return status; 236 } 237 238 /*! 239 This function makes a request to netcdf with a netCdf dimension name then return ncid of the named dimension 240 \param [in] ncid Groupd id (or File Id) 241 \param [in] dimName Name of the desired dimension 242 \param [in/out] dimId Dimension id if this dimension is found 243 \return Status code 244 */ 245 int CNetCdfInterface::inqDimId(int ncid,const StdString& dimName, int& dimId) 246 { 247 int status = nc_inq_dimid(ncid, (dimName.c_str()), &dimId); 248 if (NC_NOERR != status) 249 { 250 StdString errormsg(nc_strerror(status)); 251 StdStringStream sstr; 252 253 sstr << "Error in calling function " << "nc_inq_dimid(ncid, (dimName.c_str()), &dimId)" << std::endl 254 << errormsg << std::endl 255 << "Unable to get id of dimension, given its name : " << dimName << std::endl; 256 StdString e = sstr.str(); 257 throw CNetCdfException(e); 258 } 259 260 return status; 261 } 262 263 /*! 264 This function makes a request to netcdf with a netCdf dimension name then return ncid of the named dimension 265 \param [in] ncid Groupd id (or File Id) 266 \param [in/out] dimId Dimension id if this dimension is found 267 \return Status code 268 */ 269 int CNetCdfInterface::inqUnLimDim(int ncid, int& dimId) 270 { 271 int status = nc_inq_unlimdim(ncid, &dimId); 272 if (NC_NOERR != status) 273 { 274 StdString errormsg(nc_strerror(status)); 275 StdStringStream sstr; 276 277 sstr << "Error in calling function " << "nc_inq_dimid" << std::endl 278 << errormsg << std::endl 279 << "Unable to get id of unlimited dimension " << std::endl; 280 StdString e = sstr.str(); 281 throw CNetCdfException(e); 778 282 } 283 284 return status; 285 } 286 287 /*! 288 This function makes a request to netcdf, returns name of a dimension, given its id 289 \param [in] ncid Groupd id (or File Id) 290 \param [in] dimId Id of desired dimension 291 \param [in/out] dimName Name of desired dimension 292 \return Status code 293 */ 294 int CNetCdfInterface::inqDimName(int ncid, int dimId, StdString& dimName) 295 { 296 char fullNameIn[NC_MAX_NAME +1]; 297 int status = nc_inq_dimname(ncid, dimId, fullNameIn); 298 if (NC_NOERR != status) 299 { 300 StdString errormsg(nc_strerror(status)); 301 StdStringStream sstr; 302 303 sstr << "Error in calling function " << "nc_inq_dimname(ncid, dimId, fullNameIn)" << std::endl 304 << errormsg << std::endl 305 << "Unable to get dimension name from its id : " << dimId << std::endl; 306 StdString e = sstr.str(); 307 throw CNetCdfException(e); 308 } 309 dimName = StdString(fullNameIn); 310 return status; 311 } 312 313 /*! 314 This function makes a request to netcdf, returns length of a dimension, given its id 315 \param [in] ncid Groupd id (or File Id) 316 \param [in] dimId Id of desired dimension 317 \param [in/out] dimLen Length of desired dimension 318 \return Status code 319 */ 320 int CNetCdfInterface::inqDimLen(int ncid, int dimId, StdSize& dimLen) 321 { 322 int status = nc_inq_dimlen(ncid, dimId, &dimLen); 323 if (NC_NOERR != status) 324 { 325 StdString errormsg(nc_strerror(status)); 326 StdStringStream sstr; 327 328 sstr << "Error in calling function " << "nc_inq_dimlen(ncid, dimId, &dimLen)" << std::endl 329 << errormsg << std::endl 330 << "Unable to get dimension length from its id: " << dimId << std::endl; 331 StdString e = sstr.str(); 332 throw CNetCdfException(e); 333 } 334 335 return status; 336 } 337 338 /*! 339 This function makes a request to netcdf, returns number of dimensions of a variable, given its id 340 \param [in] ncid Groupd id (or File Id) 341 \param [in] varId Id of variable 342 \param [in/out] ndims number of dimension of the variable 343 \return Status code 344 */ 345 int CNetCdfInterface::inqVarNDims(int ncid, int varId, int& nDims) 346 { 347 int status = nc_inq_varndims(ncid, varId, &nDims); 348 if (NC_NOERR != status) 349 { 350 StdString errormsg(nc_strerror(status)); 351 StdStringStream sstr; 352 353 sstr << "Error in calling function " << "nc_inq_varndims(ncid, varId, &nDims)" << std::endl 354 << errormsg << std::endl 355 << "Unable to get the number of dimension of variable with Id : " << varId << std::endl; 356 StdString e = sstr.str(); 357 throw CNetCdfException(e); 358 } 359 360 return status; 361 } 362 363 /*! 364 This function makes a request to netcdf, returns a list of dimension ID describing the shape of the variable, given its id 365 \param [in] ncid Groupd id (or File Id) 366 \param [in] varId Id of variable 367 \param [in/out] dimIds list of dimension of the variable 368 \return Status code 369 */ 370 int CNetCdfInterface::inqVarDimId(int ncid, int varId, int* dimIds) 371 { 372 int status = nc_inq_vardimid(ncid, varId, dimIds); 373 if (NC_NOERR != status) 374 { 375 StdString errormsg(nc_strerror(status)); 376 StdStringStream sstr; 377 378 sstr << "Error in calling function " << "nc_inq_vardimid(ncid, varId, dimIds)" << std::endl 379 << errormsg << std::endl 380 << "Unable to get list of dimension id of the variable with id " << varId << std::endl; 381 StdString e = sstr.str(); 382 throw CNetCdfException(e); 383 } 384 385 return status; 386 } 387 388 /*! 389 This function makes a request to netcdf, to find all dimension in a group 390 \param [in] ncid Groupd id (or File Id) 391 \param [in/out] nDims number of list of dimension 392 \param [in/out] dimIds list of dimension in a group or any of its parent 393 \param [in] includeParents number of parents 394 \return Status code 395 */ 396 int CNetCdfInterface::inqDimIds(int ncid, int& nDims, int* dimIds, int includeParents) 397 { 398 int status = nc_inq_dimids(ncid, &nDims, dimIds, includeParents); 399 if (NC_NOERR != status) 400 { 401 StdString errormsg(nc_strerror(status)); 402 StdStringStream sstr; 403 404 sstr << "Error in calling function " << "nc_inq_dimids(ncid, &nDims, dimIds, includeParents)" << std::endl; 405 sstr << errormsg << std::endl; 406 sstr << "Unable to retrieve number of dimension in the group with id : " << ncid << std::endl; 407 sstr << "With number of Parents " << includeParents << std::endl; 408 StdString e = sstr.str(); 409 throw CNetCdfException(e); 410 } 411 412 return status; 413 } 414 415 /*! 416 This function makes a request to netcdf with a id of a prent groupd and then return id of the created group, given its name 417 \param [in] parentNcid Id of parent groupd(or File Id) 418 \param [in] grpName Name of the desired group 419 \param [in/out] grpId Group id if this group is created sucessfully 420 \return Status code 421 */ 422 int CNetCdfInterface::defGrp(int parentNcid, const StdString& grpName, int& grpId) 423 { 424 int status = nc_def_grp(parentNcid, (grpName.c_str()), &grpId); 425 if (NC_NOERR != status) 426 { 427 StdString errormsg(nc_strerror(status)); 428 StdStringStream sstr; 429 430 sstr << "Error in calling function " << "nc_def_grp(parentNcid, (grpName.c_str()), &grpId)" << std::endl; 431 sstr << errormsg << std::endl; 432 sstr << "Unable to create group Id, given its name : " << grpName << std::endl; 433 StdString e = sstr.str(); 434 throw CNetCdfException(e); 435 } 436 437 return status; 438 } 439 440 /*! 441 This function makes a request to netcdf, add a new dimension to an open netcdf in define mode 442 \param [in] ncid Id of groupd(or File Id) 443 \param [in] dimName Name of the desired dimension 444 \param [in/out] grpId Group id if this group is created sucessfully 445 \return Status code 446 */ 447 int CNetCdfInterface::defDim(int ncid, const StdString& dimName, StdSize dimLen, int& dimId) 448 { 449 int status = nc_def_dim(ncid, (dimName.c_str()), dimLen, &dimId); 450 if (NC_NOERR != status) 451 { 452 StdString errormsg(nc_strerror(status)); 453 StdStringStream sstr; 454 455 sstr << "Error in calling function " << "nc_def_dim(ncid, (dimName.c_str()), dimLen, &dimId)" << std::endl; 456 sstr << errormsg << std::endl; 457 sstr << "Unable to create dimension with name : " << dimName 458 << " and with length " << dimLen << std::endl; 459 StdString e = sstr.str(); 460 throw CNetCdfException(e); 461 } 462 463 return status; 464 } 465 466 /*! 467 This function makes a request to netcdf with its id, to add a new variable to an open netCdf in define mode, 468 return a variable id, given its name, type, the number of dimensions and list of dimension id 469 \param [in] ncid Id of groupd(or File Id) 470 \param [in] varName Name of the desired dimension 471 \param [in] xtypes One of the set of predefined netCDF data types 472 \param [in] nDims Number of dimension for the variable 473 \param [in] dimIds List of ndims dimension ids corresponding to the variable dimensions 474 \param [in/out] varId Variable id if it is added sucessfully 475 \return Status code 476 */ 477 int CNetCdfInterface::defVar(int ncid,const StdString& varName, nc_type xtype, 478 int nDims, const int dimIds[], int& varId) 479 { 480 int status = nc_def_var(ncid, (varName.c_str()), xtype, nDims, dimIds, &varId); 481 if (NC_NOERR != status) 482 { 483 StdString errormsg(nc_strerror(status)); 484 StdStringStream sstr; 485 486 sstr << "Error in calling function " << " nc_def_var(ncid, (varName.c_str()), xtype, nDims, dimIds, &varId)" << std::endl; 487 sstr << errormsg << std::endl; 488 sstr << "Unable to add a new variable with name : " << varName 489 << " with type " << xtype 490 << " and number of dimension " << nDims << std::endl; 491 StdString e = sstr.str(); 492 throw CNetCdfException(e); 493 } 494 495 return status; 496 } 497 498 /*! 499 This function makes a request to netcdf with a ncid, to set the chunking size of a variable, 500 given variable id and type of storage 501 \param [in] ncid Id groupd(or File Id) 502 \param [in] varId Id of the variable 503 \param [in] storage Type of storage (It can be : NC_CONTIGUOUS, NC_CHUNKED) 504 \param [in/out] chunkSize array list of chunk sizes 505 \return Status code 506 */ 507 int CNetCdfInterface::defVarChunking(int ncid, int varId, int storage, StdSize chunkSize[]) 508 { 509 int status = nc_def_var_chunking(ncid, varId, storage, chunkSize); 510 if (NC_NOERR != status) 511 { 512 StdString errormsg(nc_strerror(status)); 513 StdStringStream sstr; 514 515 sstr << "Error in calling function " << "nc_def_var_chunking(ncid, varId, storage, chunkSize)" << std::endl; 516 sstr << errormsg << std::endl; 517 sstr << "Unable to set chunk size of the variable with id : " << varId 518 << " and storage type " << storage << std::endl; 519 StdString e = sstr.str(); 520 throw CNetCdfException(e); 521 } 522 523 return status; 524 } 525 526 /*! 527 Set or unset the fill mode for a NetCDF file specified by its file id. 528 \param [in] ncid File id 529 \param [in] fill Define whether the fill mode should be enabled or not 530 \return Status code 531 */ 532 int CNetCdfInterface::setFill(int ncid, bool fill) 533 { 534 int old_fill_mode; 535 int status = nc_set_fill(ncid, fill ? NC_FILL : NC_NOFILL, &old_fill_mode); 536 if (NC_NOERR != status) 537 { 538 StdString errormsg(nc_strerror(status)); 539 StdStringStream sstr; 540 541 sstr << "Error when calling function nc_set_fill(ncid, fill ? NC_FILL : NC_NOFILL, &old_fill_mode)" << std::endl; 542 sstr << errormsg << std::endl; 543 sstr << "Unable to set the fill mode to : " << (fill ? "NC_FILL" : "NC_NOFILL") << std::endl; 544 StdString e = sstr.str(); 545 throw CNetCdfException(e); 546 } 547 548 return status; 549 } 550 551 /*! 552 This function makes a request to netcdf with a ncid, to set the fill parameters for a variable, 553 given variable id and type of fill 554 \param [in] ncid Id groupd(or File Id) 555 \param [in] varId Id of the variable 556 \param [in] noFill turn on/off nofill mode on a variable 557 \param [in/out] fillValue 558 \return Status code 559 */ 560 int CNetCdfInterface::defVarFill(int ncid, int varId, int noFill, void* fillValue) 561 { 562 int status = nc_def_var_fill(ncid, varId, noFill, fillValue); 563 if (NC_NOERR != status) 564 { 565 StdString errormsg(nc_strerror(status)); 566 StdStringStream sstr; 567 568 sstr << "Error in calling function " << "nc_def_var_fill(ncid, varId, noFill, fillValue)" << std::endl; 569 sstr << errormsg << std::endl; 570 sstr << "Unable to set fill parameters of the variable with id : " << varId 571 << " and fill option " << noFill << std::endl; 572 StdString e = sstr.str(); 573 throw CNetCdfException(e); 574 } 575 576 return status; 577 } 578 579 /*! 580 This function makes a request to netcdf with a ncid, to change the way read/write operations are performed 581 collectively or independently on the variable. 582 \param [in] ncid Id groupd(or File Id) 583 \param [in] varId Id of the variable 584 \param [in] noFill turn on/off nofill mode on a variable 585 \param [in/out] fillValue 586 \return Status code 587 */ 588 int CNetCdfInterface::varParAccess(int ncid, int varId, int access) 589 { 590 int status = nc_var_par_access(ncid, varId, access); 591 if (NC_NOERR != status) 592 { 593 StdString errormsg(nc_strerror(status)); 594 StdStringStream sstr; 595 596 sstr << "Error in calling function " << "nc_var_par_access(ncid, varId, access)" << std::endl; 597 sstr << errormsg << std::endl; 598 sstr << "Unable to change read/write option of the variable with id : " << varId << std::endl; 599 StdString e = sstr.str(); 600 throw CNetCdfException(e); 601 } 602 603 return status; 604 } 605 606 /*! 607 This function makes a synchronisation of the disk copy of a netCDF dataset. 608 \param [in] ncid Id groupd(or File Id) 609 \return Status code 610 */ 611 int CNetCdfInterface::sync(int ncid) 612 { 613 int status = nc_sync(ncid); 614 if (NC_NOERR != status) 615 { 616 StdString errormsg(nc_strerror(status)); 617 StdStringStream sstr; 618 619 sstr << "Error in calling function " << "nc_sync(ncid)" << std::endl; 620 sstr << errormsg << std::endl; 621 sstr << "Unable to make a synchronization of a netCDF file with id : " << ncid << std::endl; 622 StdString e = sstr.str(); 623 throw CNetCdfException(e); 624 } 625 626 return status; 627 } 628 629 /*! 630 This function makes a request to netcdf with its id, to add or change a variable attribute or gloabl attribute, 631 given its name, type, number of values provided for attribute 632 \param [in] ncid Id of groupd(or File Id) 633 \param [in] varId Id of the variable 634 \param [in] attrName Name of the attribute 635 \param [in] xtypes One of the set of predefined netCDF data types 636 \param [in] numVal Number of values 637 \param [in] op Array of values provided for attribute 638 \return Status code 639 */ 640 int CNetCdfInterface::putAtt(int ncid, int varId, const StdString& attrName, nc_type xtype, 641 StdSize numVal, const void* op) 642 { 643 int status = nc_put_att(ncid, varId, (attrName.c_str()), xtype, numVal, op); 644 if (NC_NOERR != status) 645 { 646 StdString errormsg(nc_strerror(status)); 647 StdStringStream sstr; 648 649 sstr << "Error in calling function " << "nc_put_att(ncid, varId, (attrName.c_str()), xtype, numVal, op)" << std::endl; 650 sstr << errormsg << std::endl; 651 sstr << "Unable to set attribute " << attrName << " for a variable with id : " << varId 652 << " with number of attribute " << numVal 653 << " with type " << xtype << std::endl; 654 StdString e = sstr.str(); 655 throw CNetCdfException(e); 656 } 657 658 return status; 659 } 660 661 // Some specilization of putAttributeType 662 template<> 663 int CNetCdfInterface::ncPutAttType(int ncid, int varid, const char* attrName, 664 StdSize numVal, const double* op) 665 { 666 return (nc_put_att_double(ncid, varid, attrName, NC_DOUBLE, numVal, op)); 667 } 668 669 template<> 670 int CNetCdfInterface::ncPutAttType(int ncid, int varid, const char* attrName, 671 StdSize numVal, const float* op) 672 { 673 return (nc_put_att_float(ncid, varid, attrName, NC_FLOAT, numVal, op)); 674 } 675 676 template<> 677 int CNetCdfInterface::ncPutAttType(int ncid, int varid, const char* attrName, 678 StdSize numVal, const int* op) 679 { 680 return (nc_put_att_int(ncid, varid, attrName, NC_INT, numVal, op)); 681 } 682 683 template<> 684 int CNetCdfInterface::ncPutAttType(int ncid, int varid, const char* attrName, 685 StdSize numVal, const long* op) 686 { 687 return (nc_put_att_long(ncid, varid, attrName, NC_LONG, numVal, op)); 688 } 689 690 template<> 691 int CNetCdfInterface::ncPutAttType(int ncid, int varid, const char* attrName, 692 StdSize numVal, const short* op) 693 { 694 return (nc_put_att_short(ncid, varid, attrName, NC_SHORT, numVal, op)); 695 } 696 697 698 // Some specilization of putVariableType 699 template<> 700 int CNetCdfInterface::ncPutVaraType(int ncid, int varid, const StdSize* start, const StdSize* count, const double* op) 701 { 702 return (nc_put_vara_double(ncid, varid, start, count, op)); 703 } 704 705 template<> 706 int CNetCdfInterface::ncPutVaraType(int ncid, int varid, const StdSize* start, const StdSize* count, const float* op) 707 { 708 return (nc_put_vara_float(ncid, varid, start, count, op)); 709 } 710 711 template<> 712 int CNetCdfInterface::ncPutVaraType(int ncid, int varid, const StdSize* start, const StdSize* count, const int* op) 713 { 714 return (nc_put_vara_int(ncid, varid, start, count, op)); 715 } 716 717 /*! 718 This function verifies an existence of a variable by using its name. 719 Be careful, althoug false means variable doens't exist, it could show that netCDF file doesn't either 720 \param [in] ncid Id of groupd(or File Id) 721 \param [in] attrName Name of the variable 722 \return Existence of variable 723 */ 724 bool CNetCdfInterface::isVarExisted(int ncId, const StdString& varName) 725 { 726 int varId = 0; 727 return (NC_NOERR == (nc_inq_varid(ncId, varName.c_str(), &varId))); 728 } 729 730 StdString CNetCdfInterface::openMode2String(int oMode) 731 { 732 StdString modeMes; 733 switch (oMode) 734 { 735 case NC_NOWRITE: 736 modeMes = StdString("NC_NOWRITE : Opening netCDF file with read-only access with buffering and caching access"); 737 break; 738 case NC_SHARE: 739 modeMes = StdString("NC_SHARE : Several processes can read the file concurrently"); 740 break; 741 case NC_WRITE: 742 modeMes = StdString("NC_WRITE : NetCDF file is readable and writable"); 743 break; 744 default: 745 modeMes = StdString("In the composed opening mode"); 746 break; 747 return modeMes; 748 } 749 } 750 751 StdString CNetCdfInterface::creationMode2String(int cMode) 752 { 753 StdString modeMes; 754 switch (cMode) 755 { 756 case NC_NOCLOBBER: 757 modeMes = StdString("NC_NOCLOBBER : Not overwrite an exisiting netCDF file "); 758 break; 759 case NC_SHARE: 760 modeMes = StdString("NC_SHARE : Several processes can read from and write into the file concurrently"); 761 break; 762 case NC_64BIT_OFFSET: 763 modeMes = StdString("NC_64BIT_OFFSET : NetCDF file is 64-bit offset"); 764 break; 765 case NC_NETCDF4: 766 modeMes = StdString("NC_NETCDF4 : NetCDF file is HDF5/NetCDF-4"); 767 break; 768 case NC_CLASSIC_MODEL: 769 modeMes = StdString("NC_CLASSIC_MODEL : NetCDF file is classical model"); 770 break; 771 default: 772 modeMes = StdString("In the composed creation mode"); 773 break; 774 return modeMes; 775 } 776 } 777 778 } -
XIOS/trunk/src/output/netCdfInterface.hpp
r517 r525 11 11 12 12 #include "xmlioserver_spl.hpp" 13 14 #if !defined(USING_NETCDF_PAR) 15 #include "exception.hpp" 16 #endif 17 13 18 #include "mpi.hpp" 14 19 #include "netcdf.hpp" -
XIOS/trunk/src/output/netcdf.hpp
r501 r525 24 24 25 25 #if !defined(USING_NETCDF_PAR) 26 27 26 #define NC_INDEPENDENT 0 27 #define NC_COLLECTIVE 1 28 28 #endif 29 29 … … 40 40 #endif 41 41 } 42 42 43 43 inline int nc_open_par(const char *path, int mode, MPI_Comm comm, MPI_Info info,int *ncidp) 44 { 44 { 45 45 #if defined(USING_NETCDF_PAR) 46 46 return ::nc_open_par(path, mode, comm, info, ncidp) ; … … 51 51 #endif 52 52 } 53 53 54 54 inline int nc_var_par_access(int ncid, int varid, int par_access) 55 55 {
Note: See TracChangeset
for help on using the changeset viewer.