Changeset 1158 for XIOS/dev/dev_olga/src/io
- Timestamp:
- 06/06/17 17:58:16 (7 years ago)
- Location:
- XIOS/dev/dev_olga/src/io
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
XIOS/dev/dev_olga/src/io/nc4_data_input.cpp
r967 r1158 262 262 itMapNj = itMapNi; ++itMapNj; 263 263 264 if ((CDomain::type_attr::rectilinear == domain->type)) // || this->isRectilinear(fieldId))264 if ((CDomain::type_attr::rectilinear == domain->type)) 265 265 { 266 266 // Ok, try to read some f.. attributes such as longitude and latitude … … 279 279 std::vector<StdSize> nBeginLon(1, 0), nSizeLon(1, itMapNi->second); 280 280 readFieldVariableValue(domain->lonvalue_rectilinear_read_from_file, itMapNi->first, nBeginLon, nSizeLon, true); 281 } 282 domain->fillInRectilinearLonLat(); 283 } 284 else if ((CDomain::type_attr::curvilinear == domain->type))// || (this->isCurvilinear(fieldId))) 281 } 282 } 283 else if ((CDomain::type_attr::curvilinear == domain->type)) 285 284 { 286 285 int ni = domain->ni; 287 286 int nj = domain->nj; 288 287 std::vector<StdSize> nBeginLatLon(2), nSizeLatLon(2); 289 nBeginLatLon[0] = domain->jbegin.getValue(); nBeginLatLon[1] = domain->ibegin.getValue();290 nSizeLatLon[0] = nj; nSizeLatLon[1] = ni;288 nBeginLatLon[0] = 0; nBeginLatLon[1] = 0; 289 nSizeLatLon[0] = domain->nj_glo.getValue(); nSizeLatLon[1] = domain->ni_glo.getValue(); 291 290 292 291 StdString latName = this->getLatCoordName(fieldId); 293 if (SuperClassWriter::hasVariable(latName)) //(0 != latName.compare(""))294 { 295 domain->latvalue_ 2d.resize(ni,nj);296 readFieldVariableValue(domain->latvalue_ 2d, latName, nBeginLatLon, nSizeLatLon);292 if (SuperClassWriter::hasVariable(latName)) 293 { 294 domain->latvalue_curvilinear_read_from_file.resize(domain->ni_glo,domain->nj_glo); 295 readFieldVariableValue(domain->latvalue_curvilinear_read_from_file, latName, nBeginLatLon, nSizeLatLon); 297 296 } 298 297 StdString lonName = this->getLonCoordName(fieldId); 299 if (SuperClassWriter::hasVariable(lonName)) //(0 != lonName.compare(""))300 { 301 domain->lonvalue_ 2d.resize(ni,nj);302 readFieldVariableValue(domain->lonvalue_ 2d, lonName, nBeginLatLon, nSizeLatLon);298 if (SuperClassWriter::hasVariable(lonName)) 299 { 300 domain->lonvalue_curvilinear_read_from_file.resize(domain->ni_glo,domain->nj_glo); 301 readFieldVariableValue(domain->lonvalue_curvilinear_read_from_file, lonName, nBeginLatLon, nSizeLatLon); 303 302 } 304 303 … … 307 306 308 307 int nbVertex = this->getNbVertex(fieldId); 309 if (SuperClassWriter::hasVariable(boundsLatName) || SuperClassWriter::hasVariable(boundsLonName)) //if ((0 != boundsLatName.compare("")) || (0 != boundsLonName.compare(""))) 308 if (!domain->nvertex.isEmpty() && (domain->nvertex != nbVertex)) 309 { 310 ERROR("void CNc4DataInput::readDomainAttributeValueFromFile(...)", 311 << "The domain " << domain->getDomainOutputName() 312 << " has nvertex read from file " << this->filename << " and nvertex provided from model" 313 << " are not coherent. They should be the same." << std::endl 314 << " nvertex read from file: "<< nbVertex 315 << " nvertex from model: "<< domain->nvertex << std::endl); 316 } 317 318 if (SuperClassWriter::hasVariable(boundsLatName) || SuperClassWriter::hasVariable(boundsLonName)) 310 319 domain->nvertex.setValue(nbVertex); 311 320 std::vector<StdSize> nBeginBndsLatLon(3), nSizeBndsLatLon(3); 312 nBeginBndsLatLon[0] = domain->jbegin.getValue(); nSizeBndsLatLon[0] = nj;313 nBeginBndsLatLon[1] = domain->ibegin.getValue(); nSizeBndsLatLon[1] = ni;321 nBeginBndsLatLon[0] = 0; nSizeBndsLatLon[0] = domain->nj_glo.getValue(); 322 nBeginBndsLatLon[1] = 0; nSizeBndsLatLon[1] = domain->nj_glo.getValue(); 314 323 nBeginBndsLatLon[2] = 0; nSizeBndsLatLon[2] = nbVertex; 315 324 316 if (SuperClassWriter::hasVariable(boundsLatName)) //(0 != boundsLatName.compare(""))317 { 318 domain->bounds_lat _2d.resize(nbVertex,ni,nj);319 readFieldVariableValue(domain->bounds_lat _2d, boundsLatName, nBeginBndsLatLon, nSizeBndsLatLon);320 321 } 322 if (SuperClassWriter::hasVariable(boundsLonName)) //(0 != boundsLonName.compare(""))323 { 324 domain->bounds_lon _2d.resize(nbVertex,ni,nj);325 readFieldVariableValue(domain->bounds_lon _2d, boundsLonName, nBeginBndsLatLon, nSizeBndsLatLon);326 } 325 if (SuperClassWriter::hasVariable(boundsLatName)) 326 { 327 domain->bounds_latvalue_curvilinear_read_from_file.resize(nbVertex,domain->ni_glo,domain->nj_glo); 328 readFieldVariableValue(domain->bounds_latvalue_curvilinear_read_from_file, boundsLatName, nBeginBndsLatLon, nSizeBndsLatLon); 329 330 } 331 if (SuperClassWriter::hasVariable(boundsLonName)) 332 { 333 domain->bounds_lonvalue_curvilinear_read_from_file.resize(nbVertex,domain->ni_glo,domain->nj_glo); 334 readFieldVariableValue(domain->bounds_lonvalue_curvilinear_read_from_file, boundsLonName, nBeginBndsLatLon, nSizeBndsLatLon); 335 } 327 336 } 328 337 else if ((CDomain::type_attr::unstructured == domain->type))// || (this->isUnstructured(fieldId))) 329 338 { 330 /*331 if (domain->i_index.isEmpty())332 ERROR("CNc4DataInput::readDomainAttributeValueFromFile(...)",333 << "Field '" << fieldId << std::endl334 << "Trying to read attributes from unstructured grid."335 << "i_index of domain" << domain->getId() << " is mandatory");336 337 int ni = domain->i_index.numElements();338 */339 340 int ni = domain->ni.isEmpty() ? 0 : domain->ni;341 int ibegin = domain->ibegin.isEmpty() ? 0 : domain->ibegin;342 343 if (domain->i_index.isEmpty() && (!domain->ni.isEmpty()) )344 {345 domain->i_index.resize(ni) ;346 for(int idx = 0; idx < ni; ++idx) domain->i_index(idx)=ibegin+idx ;347 }348 349 339 std::vector<StdSize> nBeginLatLon(1,0), nSizeLatLon(1,0); 350 340 nSizeLatLon[0] = domain->ni_glo.getValue(); … … 352 342 353 343 StdString latName = this->getLatCoordName(fieldId); 354 if (SuperClassWriter::hasVariable(latName)) //(0 != latName.compare("")) 355 { 356 readFieldVariableValue(globalLonLat, latName, nBeginLatLon, nSizeLatLon); 357 domain->latvalue_1d.resize(ni); 358 for (int idx = 0; idx < ni; ++idx) 359 domain->latvalue_1d(idx) = globalLonLat(domain->i_index(idx)); 344 if (SuperClassWriter::hasVariable(latName)) 345 { 346 domain->latvalue_unstructured_read_from_file.resize(domain->ni_glo); 347 readFieldVariableValue(domain->latvalue_unstructured_read_from_file, latName, nBeginLatLon, nSizeLatLon); 360 348 } 361 349 … … 363 351 if (SuperClassWriter::hasVariable(lonName)) //(0 != lonName.compare("")) 364 352 { 365 readFieldVariableValue(globalLonLat, lonName, nBeginLatLon, nSizeLatLon); 366 domain->lonvalue_1d.resize(ni); 367 for (int idx = 0; idx < ni; ++idx) 368 domain->lonvalue_1d(idx) = globalLonLat(domain->i_index(idx)); 353 // readFieldVariableValue(globalLonLat, lonName, nBeginLatLon, nSizeLatLon); 354 domain->lonvalue_unstructured_read_from_file.resize(domain->ni_glo); 355 readFieldVariableValue(domain->lonvalue_unstructured_read_from_file, lonName, nBeginLatLon, nSizeLatLon); 369 356 } 370 357 … … 373 360 374 361 int nbVertex = this->getNbVertex(fieldId); 375 if (SuperClassWriter::hasVariable(boundsLatName) || SuperClassWriter::hasVariable(boundsLonName)) // (0 != boundsLatName.compare("")) || (0 != boundsLonName.compare(""))) 362 if (!domain->nvertex.isEmpty() && (domain->nvertex != nbVertex)) 363 { 364 ERROR("void CNc4DataInput::readDomainAttributeValueFromFile(...)", 365 << "The domain " << domain->getDomainOutputName() 366 << " has nvertex read from file " << this->filename << " and nvertex provided from model" 367 << " are not coherent. They should be the same." << std::endl 368 << " nvertex read from file: "<< nbVertex 369 << " nvertex from model: "<< domain->nvertex << std::endl); 370 } 371 372 if (SuperClassWriter::hasVariable(boundsLatName) || SuperClassWriter::hasVariable(boundsLonName)) 376 373 domain->nvertex.setValue(nbVertex); 377 374 … … 380 377 nBeginBndsLatLon[1] = 0; nSizeBndsLatLon[1] = nbVertex; 381 378 382 if (SuperClassWriter::hasVariable(boundsLatName)) //(0 != boundsLatName.compare("")) 383 { 384 CArray<double,2> globalBndsLonLat(nSizeBndsLatLon[1], nSizeBndsLatLon[0]); 385 readFieldVariableValue(globalBndsLonLat, boundsLatName, nBeginBndsLatLon, nSizeBndsLatLon); 386 domain->bounds_lat_1d.resize(nbVertex,ni); 387 for (int idx = 0; idx < ni; ++idx) 388 for (int jdx = 0; jdx < nbVertex; ++jdx) 389 domain->bounds_lat_1d(jdx,idx) = globalBndsLonLat(jdx, domain->i_index(idx)); 390 } 391 392 if (SuperClassWriter::hasVariable(boundsLonName)) //(0 != boundsLonName.compare("")) 393 { 394 CArray<double,2> globalBndsLonLat(nSizeBndsLatLon[1], nSizeBndsLatLon[0]); 395 readFieldVariableValue(globalBndsLonLat, boundsLonName, nBeginBndsLatLon, nSizeBndsLatLon); 396 domain->bounds_lon_1d.resize(nbVertex,ni); 397 for (int idx = 0; idx < ni; ++idx) 398 for (int jdx = 0; jdx < nbVertex; ++jdx) 399 domain->bounds_lon_1d(jdx,idx) = globalBndsLonLat(jdx, domain->i_index(idx)); 400 } 401 } 379 if (SuperClassWriter::hasVariable(boundsLatName)) 380 { 381 domain->bounds_latvalue_unstructured_read_from_file.resize(nSizeBndsLatLon[1], nSizeBndsLatLon[0]); 382 readFieldVariableValue(domain->bounds_latvalue_unstructured_read_from_file, boundsLatName, nBeginBndsLatLon, nSizeBndsLatLon); 383 } 384 385 if (SuperClassWriter::hasVariable(boundsLonName)) 386 { 387 domain->bounds_lonvalue_unstructured_read_from_file.resize(nSizeBndsLatLon[1], nSizeBndsLatLon[0]); 388 readFieldVariableValue(domain->bounds_lonvalue_unstructured_read_from_file, boundsLonName, nBeginBndsLatLon, nSizeBndsLatLon); 389 } 390 } 391 domain->fillInLonLat(); 402 392 } 403 393 … … 421 411 if (this->isRectilinear(fieldId) || this->isCurvilinear(fieldId)) 422 412 { 413 if (!domain->nj_glo.isEmpty() && (domain->nj_glo != itMapNj->second)) 414 { 415 ERROR("void CNc4DataInput::readDomainAttributesFromFile(...)", 416 << "The domain " << domain->getDomainOutputName() 417 << " has nj_glo read from file " << this->filename << " and nj_glo provided from model" 418 << " are not coherent. They should be the same." << std::endl 419 << " nj_glo read from file: "<< itMapNj->second 420 << " nj_glo from model: "<< domain->nj_glo << std::endl); 421 } 423 422 domain->nj_glo.setValue(itMapNj->second); 423 424 if (!domain->ni_glo.isEmpty() && (domain->ni_glo != itMapNi->second)) 425 { 426 ERROR("void CNc4DataInput::readDomainAttributesFromFile(...)", 427 << "The domain " << domain->getDomainOutputName() 428 << " has ni_glo read from file " << this->filename << " and ni_glo provided from model" 429 << " are not coherent. They should be the same." << std::endl 430 << " ni_glo read from file: "<< itMapNi->second 431 << " ni_glo from model: "<< domain->ni_glo << std::endl); 432 } 424 433 domain->ni_glo.setValue(itMapNi->second); 425 434 } … … 427 436 { 428 437 domain->nj_glo.setValue(1); 438 439 if (!domain->ni_glo.isEmpty() && (domain->ni_glo != itMapNi->second)) 440 { 441 ERROR("void CNc4DataInput::readDomainAttributesFromFile(...)", 442 << "The domain " << domain->getDomainOutputName() 443 << " has ni_glo read from file " << this->filename << " and ni_glo provided from model" 444 << " are not coherent. They should be the same." << std::endl 445 << " ni_glo read from file: "<< itMapNi->second 446 << " ni_glo from model: "<< domain->ni_glo << std::endl); 447 } 429 448 domain->ni_glo.setValue(itMapNi->second); 430 449 } … … 444 463 iteMap = dimSizeMap.end(); 445 464 for (int i = 0; i < elementPosition; ++i, ++itMapN) {} 465 466 if (!axis->n_glo.isEmpty() && (axis->n_glo != itMapN->second)) 467 { 468 ERROR("void CNc4DataInput::readAxisAttributesFromFile(...)", 469 << "The axis " << axis->getAxisOutputName() 470 << " has n_glo read from file " << this->filename << " and n_glo provided from model" 471 << " are not coherent. They should be the same." << std::endl 472 << " n_glo read from file: "<< itMapN->second 473 << " n_glo from model: "<< axis->n_glo << std::endl); 474 } 446 475 axis->n_glo.setValue(itMapN->second); 447 476 } … … 483 512 int elementPosition, const StdString& fieldId) 484 513 { 485 // std::list<std::pair<StdString, StdSize> >::const_iterator itMapN = dimSizeMap.begin(), 486 // iteMap = dimSizeMap.end(); 487 // for (int i = 0; i < elementPosition; ++i, ++itMapN) {} 488 // axis->n_glo.setValue(itMapN->second); 514 /*Nothing to do */ 489 515 } 490 516 … … 499 525 int elementPosition, const StdString& fieldId) 500 526 { 501 // std::list<std::pair<StdString, StdSize> >::const_iterator itMapN = dimSizeMap.begin(), 502 // iteMap = dimSizeMap.end(); 503 // for (int i = 0; i < elementPosition; ++i, ++itMapN) {} 504 // 505 // { // Read axis value 506 // std::vector<StdSize> nBegin(1, 0), nSize(1, itMapN->second); 507 // CArray<double,1> readAxisValue(itMapN->second); 508 // readFieldVariableValue(readAxisValue, itMapN->first, nBegin, nSize, true); 509 // int begin = 0, n = itMapN->second; 510 // if (!axis->begin.isEmpty()) begin = axis->begin.getValue(); 511 // if (!axis->n.isEmpty()) n = axis->n.getValue(); 512 // axis->value.resize(n); 513 // for (int i = 0; i < n; ++i) axis->value(i) = readAxisValue(begin + i); 514 // } 527 /*Nothing to do */ 515 528 } 516 529 -
XIOS/dev/dev_olga/src/io/nc4_data_output.cpp
r1144 r1158 11 11 #include "netCdfException.hpp" 12 12 #include "exception.hpp" 13 13 #include "timer.hpp" 14 #include "uuid.hpp" 14 15 namespace xios 15 16 { 16 17 /// ////////////////////// Dfinitions ////////////////////// /// 17 18 CNc4DataOutput::CNc4DataOutput 18 ( const StdString & filename, bool exist)19 (CFile* file, const StdString & filename, bool exist) 19 20 : SuperClass() 20 21 , SuperClassWriter(filename, exist) 21 22 , filename(filename) 22 { 23 SuperClass::type = MULTI_FILE; 23 , file(file),hasTimeInstant(false),hasTimeCentered(false), timeCounterType(none) 24 { 25 SuperClass::type = MULTI_FILE; 24 26 } 25 27 26 28 CNc4DataOutput::CNc4DataOutput 27 ( const StdString & filename, bool exist, bool useClassicFormat, bool useCFConvention,29 (CFile* file, const StdString & filename, bool exist, bool useClassicFormat, bool useCFConvention, 28 30 MPI_Comm comm_file, bool multifile, bool isCollective, const StdString& timeCounterName) 29 31 : SuperClass() … … 32 34 , filename(filename) 33 35 , isCollective(isCollective) 34 { 35 SuperClass::type = (multifile) ? MULTI_FILE : ONE_FILE; 36 , file(file),hasTimeInstant(false),hasTimeCentered(false), timeCounterType(none) 37 { 38 SuperClass::type = (multifile) ? MULTI_FILE : ONE_FILE; 36 39 } 37 40 … … 60 63 } 61 64 62 63 65 CContext* context = CContext::getCurrent() ; 64 66 CContextServer* server=context->server ; … … 78 80 int nvertex = (domain->nvertex.isEmpty()) ? 0 : domain->nvertex; 79 81 80 StdString dimXid, dimYid ; 81 82 83 StdString dimXid, dimYid ; 84 85 nc_type typePrec ; 86 if (domain->prec.isEmpty()) typePrec = NC_FLOAT ; 87 else if (domain->prec==4) typePrec = NC_FLOAT ; 88 else if (domain->prec==8) typePrec = NC_DOUBLE ; 89 82 90 bool isRegularDomain = (domain->type == CDomain::type_attr::rectilinear); 83 91 switch (domain->type) … … 209 217 { 210 218 case CDomain::type_attr::curvilinear : 211 SuperClassWriter::addVariable(latid, NC_FLOAT, dim0);212 SuperClassWriter::addVariable(lonid, NC_FLOAT, dim0);219 SuperClassWriter::addVariable(latid, typePrec, dim0); 220 SuperClassWriter::addVariable(lonid, typePrec, dim0); 213 221 break ; 214 222 case CDomain::type_attr::rectilinear : 215 SuperClassWriter::addVariable(latid, NC_FLOAT, dim0);216 SuperClassWriter::addVariable(lonid, NC_FLOAT, dim1);223 SuperClassWriter::addVariable(latid, typePrec, dim0); 224 SuperClassWriter::addVariable(lonid, typePrec, dim1); 217 225 break ; 218 226 } … … 230 238 dim0.push_back(dimXid); 231 239 dim0.push_back(dimVertId); 232 SuperClassWriter::addVariable(bounds_lonid, NC_FLOAT, dim0);233 SuperClassWriter::addVariable(bounds_latid, NC_FLOAT, dim0);240 SuperClassWriter::addVariable(bounds_lonid, typePrec, dim0); 241 SuperClassWriter::addVariable(bounds_latid, typePrec, dim0); 234 242 } 235 243 } … … 256 264 if (domain->hasArea) 257 265 { 258 SuperClassWriter::addVariable(areaId, NC_FLOAT, dim0);266 SuperClassWriter::addVariable(areaId, typePrec, dim0); 259 267 SuperClassWriter::addAttribute("standard_name", StdString("cell_area"), &areaId); 260 268 SuperClassWriter::addAttribute("units", StdString("m2"), &areaId); … … 311 319 lonid = StdString("nav_lon").append(appendDomid); 312 320 latid = StdString("nav_lat").append(appendDomid); 313 SuperClassWriter::addVariable(latid, NC_FLOAT, dim0);314 SuperClassWriter::addVariable(lonid, NC_FLOAT, dim0);321 SuperClassWriter::addVariable(latid, typePrec, dim0); 322 SuperClassWriter::addVariable(lonid, typePrec, dim0); 315 323 break; 316 324 … … 320 328 lonid = StdString("lon").append(appendDomid); 321 329 latid = StdString("lat").append(appendDomid); 322 SuperClassWriter::addVariable(latid, NC_FLOAT, dim0);323 SuperClassWriter::addVariable(lonid, NC_FLOAT, dim1);330 SuperClassWriter::addVariable(latid, typePrec, dim0); 331 SuperClassWriter::addVariable(lonid, typePrec, dim1); 324 332 break; 325 333 } … … 342 350 dim0.push_back(dimXid); 343 351 dim0.push_back(dimVertId); 344 SuperClassWriter::addVariable(bounds_lonid, NC_FLOAT, dim0);345 SuperClassWriter::addVariable(bounds_latid, NC_FLOAT, dim0);352 SuperClassWriter::addVariable(bounds_lonid, typePrec, dim0); 353 SuperClassWriter::addVariable(bounds_latid, typePrec, dim0); 346 354 } 347 355 } … … 351 359 dim0.clear(); 352 360 dim0.push_back(dimYid); dim0.push_back(dimXid); 353 SuperClassWriter::addVariable(areaId, NC_FLOAT, dim0);361 SuperClassWriter::addVariable(areaId, typePrec, dim0); 354 362 SuperClassWriter::addAttribute("standard_name", StdString("cell_area"), &areaId); 355 363 SuperClassWriter::addAttribute("units", StdString("m2"), &areaId); … … 492 500 if (SuperClass::type==MULTI_FILE) return ; 493 501 502 nc_type typePrec ; 503 if (domain->prec.isEmpty()) typePrec = NC_FLOAT ; 504 else if (domain->prec==4) typePrec = NC_FLOAT ; 505 else if (domain->prec==8) typePrec = NC_DOUBLE ; 506 494 507 std::vector<StdString> dim0; 495 508 StdString domid = domain->getDomainOutputName(); … … 543 556 dim0.clear(); 544 557 dim0.push_back(dimNode); 545 SuperClassWriter::addVariable(node_x, NC_FLOAT, dim0);558 SuperClassWriter::addVariable(node_x, typePrec, dim0); 546 559 SuperClassWriter::addAttribute("standard_name", StdString("longitude"), &node_x); 547 560 SuperClassWriter::addAttribute("long_name", StdString("Longitude of mesh nodes."), &node_x); 548 561 SuperClassWriter::addAttribute("units", StdString("degrees_east"), &node_x); 549 SuperClassWriter::addVariable(node_y, NC_FLOAT, dim0);562 SuperClassWriter::addVariable(node_y, typePrec, dim0); 550 563 SuperClassWriter::addAttribute("standard_name", StdString("latitude"), &node_y); 551 564 SuperClassWriter::addAttribute("long_name", StdString("Latitude of mesh nodes."), &node_y); … … 562 575 dim0.clear(); 563 576 dim0.push_back(dimNode); 564 SuperClassWriter::addVariable(node_x, NC_FLOAT, dim0);577 SuperClassWriter::addVariable(node_x, typePrec, dim0); 565 578 SuperClassWriter::addAttribute("standard_name", StdString("longitude"), &node_x); 566 579 SuperClassWriter::addAttribute("long_name", StdString("Longitude of mesh nodes."), &node_x); 567 580 SuperClassWriter::addAttribute("units", StdString("degrees_east"), &node_x); 568 SuperClassWriter::addVariable(node_y, NC_FLOAT, dim0);581 SuperClassWriter::addVariable(node_y, typePrec, dim0); 569 582 SuperClassWriter::addAttribute("standard_name", StdString("latitude"), &node_y); 570 583 SuperClassWriter::addAttribute("long_name", StdString("Latitude of mesh nodes."), &node_y); … … 576 589 dim0.clear(); 577 590 dim0.push_back(dimEdge); 578 SuperClassWriter::addVariable(edge_x, NC_FLOAT, dim0);591 SuperClassWriter::addVariable(edge_x, typePrec, dim0); 579 592 SuperClassWriter::addAttribute("standard_name", StdString("longitude"), &edge_x); 580 593 SuperClassWriter::addAttribute("long_name", StdString("Characteristic longitude of mesh edges."), &edge_x); 581 594 SuperClassWriter::addAttribute("units", StdString("degrees_east"), &edge_x); 582 SuperClassWriter::addVariable(edge_y, NC_FLOAT, dim0);595 SuperClassWriter::addVariable(edge_y, typePrec, dim0); 583 596 SuperClassWriter::addAttribute("standard_name", StdString("latitude"), &edge_y); 584 597 SuperClassWriter::addAttribute("long_name", StdString("Characteristic latitude of mesh edges."), &edge_y); … … 602 615 dim0.clear(); 603 616 dim0.push_back(dimNode); 604 SuperClassWriter::addVariable(node_x, NC_FLOAT, dim0);617 SuperClassWriter::addVariable(node_x, typePrec, dim0); 605 618 SuperClassWriter::addAttribute("standard_name", StdString("longitude"), &node_x); 606 619 SuperClassWriter::addAttribute("long_name", StdString("Longitude of mesh nodes."), &node_x); 607 620 SuperClassWriter::addAttribute("units", StdString("degrees_east"), &node_x); 608 SuperClassWriter::addVariable(node_y, NC_FLOAT, dim0);621 SuperClassWriter::addVariable(node_y, typePrec, dim0); 609 622 SuperClassWriter::addAttribute("standard_name", StdString("latitude"), &node_y); 610 623 SuperClassWriter::addAttribute("long_name", StdString("Latitude of mesh nodes."), &node_y); … … 618 631 dim0.clear(); 619 632 dim0.push_back(dimEdge); 620 SuperClassWriter::addVariable(edge_x, NC_FLOAT, dim0);633 SuperClassWriter::addVariable(edge_x, typePrec, dim0); 621 634 SuperClassWriter::addAttribute("standard_name", StdString("longitude"), &edge_x); 622 635 SuperClassWriter::addAttribute("long_name", StdString("Characteristic longitude of mesh edges."), &edge_x); 623 636 SuperClassWriter::addAttribute("units", StdString("degrees_east"), &edge_x); 624 SuperClassWriter::addVariable(edge_y, NC_FLOAT, dim0);637 SuperClassWriter::addVariable(edge_y, typePrec, dim0); 625 638 SuperClassWriter::addAttribute("standard_name", StdString("latitude"), &edge_y); 626 639 SuperClassWriter::addAttribute("long_name", StdString("Characteristic latitude of mesh edges."), &edge_y); … … 640 653 dim0.clear(); 641 654 dim0.push_back(dimFace); 642 SuperClassWriter::addVariable(face_x, NC_FLOAT, dim0);655 SuperClassWriter::addVariable(face_x, typePrec, dim0); 643 656 SuperClassWriter::addAttribute("standard_name", StdString("longitude"), &face_x); 644 657 SuperClassWriter::addAttribute("long_name", StdString("Characteristic longitude of mesh faces."), &face_x); 645 658 SuperClassWriter::addAttribute("units", StdString("degrees_east"), &face_x); 646 SuperClassWriter::addVariable(face_y, NC_FLOAT, dim0);659 SuperClassWriter::addVariable(face_y, typePrec, dim0); 647 660 SuperClassWriter::addAttribute("standard_name", StdString("latitude"), &face_y); 648 661 SuperClassWriter::addAttribute("long_name", StdString("Characteristic latitude of mesh faces."), &face_y); … … 906 919 string areaId = "area" + appendDomid; 907 920 921 nc_type typePrec ; 922 if (domain->prec.isEmpty()) typePrec = NC_FLOAT ; 923 else if (domain->prec==4) typePrec = NC_FLOAT ; 924 else if (domain->prec==8) typePrec = NC_DOUBLE ; 925 908 926 int nvertex = (domain->nvertex.isEmpty()) ? 0 : domain->nvertex; 909 927 … … 965 983 if (domain->hasLonLat) 966 984 { 967 SuperClassWriter::addVariable(latid, NC_FLOAT, dim0);968 SuperClassWriter::addVariable(lonid, NC_FLOAT, dim0);985 SuperClassWriter::addVariable(latid, typePrec, dim0); 986 SuperClassWriter::addVariable(lonid, typePrec, dim0); 969 987 this->writeAxisAttributes(lonid, "", "longitude", "Longitude", "degrees_east", domid); 970 988 if (domain->hasBounds) SuperClassWriter::addAttribute("bounds",bounds_lonid, &lonid); … … 978 996 dim0.push_back(dimXid); 979 997 dim0.push_back(dimVertId); 980 SuperClassWriter::addVariable(bounds_lonid, NC_FLOAT, dim0);981 SuperClassWriter::addVariable(bounds_latid, NC_FLOAT, dim0);998 SuperClassWriter::addVariable(bounds_lonid, typePrec, dim0); 999 SuperClassWriter::addVariable(bounds_latid, typePrec, dim0); 982 1000 } 983 1001 … … 986 1004 if (domain->hasArea) 987 1005 { 988 SuperClassWriter::addVariable(areaId, NC_FLOAT, dim0);1006 SuperClassWriter::addVariable(areaId, typePrec, dim0); 989 1007 SuperClassWriter::addAttribute("standard_name", StdString("cell_area"), &areaId); 990 1008 SuperClassWriter::addAttribute("units", StdString("m2"), &areaId); … … 1021 1039 if (domain->hasLonLat) 1022 1040 { 1023 SuperClassWriter::addVariable(latid, NC_FLOAT, dim0);1024 SuperClassWriter::addVariable(lonid, NC_FLOAT, dim0);1041 SuperClassWriter::addVariable(latid, typePrec, dim0); 1042 SuperClassWriter::addVariable(lonid, typePrec, dim0); 1025 1043 1026 1044 this->writeAxisAttributes(lonid, "", "longitude", "Longitude", "degrees_east", domid); … … 1036 1054 dim0.push_back(dimXid); 1037 1055 dim0.push_back(dimVertId); 1038 SuperClassWriter::addVariable(bounds_lonid, NC_FLOAT, dim0);1039 SuperClassWriter::addVariable(bounds_latid, NC_FLOAT, dim0);1056 SuperClassWriter::addVariable(bounds_lonid, typePrec, dim0); 1057 SuperClassWriter::addVariable(bounds_latid, typePrec, dim0); 1040 1058 } 1041 1059 … … 1044 1062 dim0.clear(); 1045 1063 dim0.push_back(dimXid); 1046 SuperClassWriter::addVariable(areaId, NC_FLOAT, dim0);1064 SuperClassWriter::addVariable(areaId, typePrec, dim0); 1047 1065 SuperClassWriter::addAttribute("standard_name", StdString("cell_area"), &areaId); 1048 1066 SuperClassWriter::addAttribute("units", StdString("m2"), &areaId); … … 1111 1129 void CNc4DataOutput::writeAxis_(CAxis* axis) 1112 1130 { 1113 CContext* context = CContext::getCurrent();1114 1115 1131 if (axis->IsWritten(this->filename)) return; 1116 1132 axis->checkAttributes(); … … 1130 1146 else setWrittenAxis(axisid); 1131 1147 1148 nc_type typePrec ; 1149 if (axis->prec.isEmpty()) typePrec = NC_FLOAT ; 1150 else if (axis->prec==4) typePrec = NC_FLOAT ; 1151 else if (axis->prec==8) typePrec = NC_DOUBLE ; 1152 1153 if (!axis->label.isEmpty()) typePrec = NC_CHAR ; 1154 string strId="str_len" ; 1132 1155 try 1133 1156 { 1134 1157 SuperClassWriter::addDimension(axisid, zoom_size); 1158 if (!axis->label.isEmpty()) SuperClassWriter::addDimension(strId, stringArrayLen); 1135 1159 if (axis->hasValue) 1136 1160 { 1137 1161 dims.push_back(axisid); 1138 SuperClassWriter::addVariable(axisid, NC_FLOAT, dims); 1162 if (!axis->label.isEmpty()) dims.push_back(strId); 1163 SuperClassWriter::addVariable(axisid, typePrec, dims); 1139 1164 1140 1165 if (!axis->name.isEmpty()) … … 1162 1187 { 1163 1188 dims.push_back("axis_nbounds"); 1164 SuperClassWriter::addVariable(axisBoundsId, NC_FLOAT, dims);1189 SuperClassWriter::addVariable(axisBoundsId, typePrec, dims); 1165 1190 SuperClassWriter::addAttribute("bounds", axisBoundsId, &axisid); 1166 1191 } … … 1178 1203 case MULTI_FILE: 1179 1204 { 1180 // CArray<double,1> axis_value(axis->zoom_n);1181 // for (int i = 0; i < axis->zoom_n; i++) axis_value(i) = axis->value(i);1182 1205 SuperClassWriter::writeData(axis_value, axisid, isCollective, 0); 1183 1206 1184 if (!axis->bounds.isEmpty() )1207 if (!axis->bounds.isEmpty() && axis->label.isEmpty()) 1185 1208 SuperClassWriter::writeData(axis->bounds, axisBoundsId, isCollective, 0); 1186 1209 1210 // Need to check after 1211 if (! axis->label.isEmpty()) SuperClassWriter::writeData(axis->label_srv, axisid, isCollective, 0); 1212 1187 1213 SuperClassWriter::definition_start(); 1188 1189 1214 break; 1190 1215 } 1191 1216 case ONE_FILE: 1192 1217 { 1193 // CArray<double,1> axis_value(axis->zoom_n);1194 // axis_value = axis->value;1195 1218 std::vector<StdSize> start(1), startBounds(2) ; 1196 1219 std::vector<StdSize> count(1), countBounds(2) ; … … 1201 1224 SuperClassWriter::writeData(axis_value, axisid, isCollective, 0, &start, &count); 1202 1225 1203 if (!axis->bounds.isEmpty() )1226 if (!axis->bounds.isEmpty()&& axis->label.isEmpty()) 1204 1227 { 1205 1228 axis_bounds.resize(2, indexToWrite.numElements()); … … 1211 1234 SuperClassWriter::writeData(axis->bounds, axisBoundsId, isCollective, 0, &startBounds, &countBounds); 1212 1235 } 1236 1237 // Need to check after 1238 if (! axis->label.isEmpty()) SuperClassWriter::writeData(axis->label_srv, axisid, isCollective, 0); 1213 1239 1214 1240 SuperClassWriter::definition_start(); … … 1233 1259 ERROR("CNc4DataOutput::writeAxis_(CAxis* axis)", << msg); 1234 1260 } 1235 1236 axis->addRelFile(this->filename); 1261 axis->addRelFile(this->filename); 1237 1262 } 1238 1263 … … 1247 1272 else setWrittenAxis(scalaId); 1248 1273 1274 nc_type typePrec ; 1275 if (scalar->prec.isEmpty()) typePrec = NC_FLOAT ; 1276 else if (scalar->prec==4) typePrec = NC_FLOAT ; 1277 else if (scalar->prec==8) typePrec = NC_DOUBLE ; 1278 1279 1249 1280 try 1250 1281 { … … 1253 1284 // dims.push_back(scalaId); 1254 1285 std::vector<StdString> dims; 1255 SuperClassWriter::addVariable(scalaId, NC_FLOAT, dims);1286 SuperClassWriter::addVariable(scalaId, typePrec, dims); 1256 1287 1257 1288 if (!scalar->name.isEmpty()) … … 1550 1581 void CNc4DataOutput::writeField_(CField* field) 1551 1582 { 1552 1553 1554 1555 1556 1557 1583 CContext* context = CContext::getCurrent() ; 1584 CContextServer* server=context->server ; 1585 1586 std::vector<StdString> dims, coodinates; 1587 CGrid* grid = field->grid; 1588 if (!grid->doGridHaveDataToWrite()) 1558 1589 if (SuperClass::type==MULTI_FILE) return ; 1559 1590 1560 CArray<int,1> axisDomainOrder = grid->axis_domain_order; 1561 int numElement = axisDomainOrder.numElements(), idxDomain = 0, idxAxis = 0, idxScalar = 0; 1562 std::vector<StdString> domainList = grid->getDomainList(); 1563 std::vector<StdString> axisList = grid->getAxisList(); 1564 std::vector<StdString> scalarList = grid->getScalarList(); 1565 1566 StdString timeid = getTimeCounterName(); 1567 StdString dimXid,dimYid; 1568 std::deque<StdString> dimIdList, dimCoordList; 1569 bool hasArea = false; 1570 StdString cellMeasures = "area:"; 1571 bool compressedOutput = !field->indexed_output.isEmpty() && field->indexed_output; 1572 1573 for (int i = 0; i < numElement; ++i) 1574 { 1575 if (2 == axisDomainOrder(i)) 1576 { 1577 CDomain* domain = CDomain::get(domainList[idxDomain]); 1578 StdString domId = domain->getDomainOutputName(); 1579 StdString appendDomId = singleDomain ? "" : "_" + domId ; 1580 1581 if (compressedOutput && domain->isCompressible() && domain->type != CDomain::type_attr::unstructured) 1582 { 1583 dimIdList.push_back(domId + "_points"); 1584 field->setUseCompressedOutput(); 1585 } 1586 1587 switch (domain->type) 1588 { 1589 case CDomain::type_attr::curvilinear: 1590 if (!compressedOutput || !domain->isCompressible()) 1591 { 1592 dimXid = StdString("x").append(appendDomId); 1593 dimIdList.push_back(dimXid); 1594 dimYid = StdString("y").append(appendDomId); 1595 dimIdList.push_back(dimYid); 1596 } 1597 dimCoordList.push_back(StdString("nav_lon").append(appendDomId)); 1598 dimCoordList.push_back(StdString("nav_lat").append(appendDomId)); 1599 break ; 1600 case CDomain::type_attr::rectilinear: 1601 if (!compressedOutput || !domain->isCompressible()) 1602 { 1603 dimXid = StdString("lon").append(appendDomId); 1604 dimIdList.push_back(dimXid); 1605 dimYid = StdString("lat").append(appendDomId); 1606 dimIdList.push_back(dimYid); 1607 } 1608 break ; 1609 case CDomain::type_attr::unstructured: 1610 { 1611 if (SuperClassWriter::useCFConvention) 1612 { 1613 dimXid = StdString("cell").append(appendDomId); 1614 dimIdList.push_back(dimXid); 1615 dimCoordList.push_back(StdString("lon").append(appendDomId)); 1616 dimCoordList.push_back(StdString("lat").append(appendDomId)); 1591 CArray<int,1> axisDomainOrder = grid->axis_domain_order; 1592 int numElement = axisDomainOrder.numElements(), idxDomain = 0, idxAxis = 0, idxScalar = 0; 1593 std::vector<StdString> domainList = grid->getDomainList(); 1594 std::vector<StdString> axisList = grid->getAxisList(); 1595 std::vector<StdString> scalarList = grid->getScalarList(); 1596 1597 StdString timeid = getTimeCounterName(); 1598 StdString dimXid,dimYid; 1599 std::deque<StdString> dimIdList, dimCoordList; 1600 bool hasArea = false; 1601 StdString cellMeasures = "area:"; 1602 bool compressedOutput = !field->indexed_output.isEmpty() && field->indexed_output; 1603 1604 for (int i = 0; i < numElement; ++i) 1605 { 1606 if (2 == axisDomainOrder(i)) 1607 { 1608 CDomain* domain = CDomain::get(domainList[idxDomain]); 1609 StdString domId = domain->getDomainOutputName(); 1610 StdString appendDomId = singleDomain ? "" : "_" + domId ; 1611 1612 if (compressedOutput && domain->isCompressible() && domain->type != CDomain::type_attr::unstructured) 1613 { 1614 dimIdList.push_back(domId + "_points"); 1615 field->setUseCompressedOutput(); 1616 } 1617 1618 switch (domain->type) 1619 { 1620 case CDomain::type_attr::curvilinear: 1621 if (!compressedOutput || !domain->isCompressible()) 1622 { 1623 dimXid = StdString("x").append(appendDomId); 1624 dimIdList.push_back(dimXid); 1625 dimYid = StdString("y").append(appendDomId); 1626 dimIdList.push_back(dimYid); 1627 } 1628 dimCoordList.push_back(StdString("nav_lon").append(appendDomId)); 1629 dimCoordList.push_back(StdString("nav_lat").append(appendDomId)); 1630 break ; 1631 case CDomain::type_attr::rectilinear: 1632 if (!compressedOutput || !domain->isCompressible()) 1633 { 1634 dimXid = StdString("lon").append(appendDomId); 1635 dimIdList.push_back(dimXid); 1636 dimYid = StdString("lat").append(appendDomId); 1637 dimIdList.push_back(dimYid); 1638 } 1639 break ; 1640 case CDomain::type_attr::unstructured: 1641 { 1642 if (SuperClassWriter::useCFConvention) 1643 { 1644 dimXid = StdString("cell").append(appendDomId); 1645 dimIdList.push_back(dimXid); 1646 dimCoordList.push_back(StdString("lon").append(appendDomId)); 1647 dimCoordList.push_back(StdString("lat").append(appendDomId)); 1648 } 1649 else 1650 { 1651 StdString domainName = domain->name; 1652 if (domain->nvertex == 1) 1653 { 1654 dimXid = "n" + domainName + "_node"; 1655 dimIdList.push_back(dimXid); 1656 dimCoordList.push_back(StdString(domainName + "_node_x")); 1657 dimCoordList.push_back(StdString(domainName + "_node_y")); 1658 } 1659 else if (domain->nvertex == 2) 1660 { 1661 dimXid = "n" + domainName + "_edge"; 1662 dimIdList.push_back(dimXid); 1663 dimCoordList.push_back(StdString(domainName + "_edge_x")); 1664 dimCoordList.push_back(StdString(domainName + "_edge_y")); 1665 } 1666 else 1667 { 1668 dimXid = "n" + domainName + "_face"; 1669 dimIdList.push_back(dimXid); 1670 dimCoordList.push_back(StdString(domainName + "_face_x")); 1671 dimCoordList.push_back(StdString(domainName + "_face_y")); 1672 } 1673 } // ugrid convention 1674 } // case unstructured domain 1675 } 1676 1677 if (domain->hasArea) 1678 { 1679 hasArea = true; 1680 cellMeasures += " area" + appendDomId; 1681 } 1682 ++idxDomain; 1617 1683 } 1618 else 1619 { 1620 StdString domainName = domain->name; 1621 if (domain->nvertex == 1) 1684 else if (1 == axisDomainOrder(i)) 1685 { 1686 CAxis* axis = CAxis::get(axisList[idxAxis]); 1687 StdString axisId = axis->getAxisOutputName(); 1688 1689 if (compressedOutput && axis->isCompressible()) 1622 1690 { 1623 dimXid = "n" + domainName + "_node"; 1624 dimIdList.push_back(dimXid); 1625 dimCoordList.push_back(StdString(domainName + "_node_x")); 1626 dimCoordList.push_back(StdString(domainName + "_node_y")); 1627 } 1628 else if (domain->nvertex == 2) 1629 { 1630 dimXid = "n" + domainName + "_edge"; 1631 dimIdList.push_back(dimXid); 1632 dimCoordList.push_back(StdString(domainName + "_edge_x")); 1633 dimCoordList.push_back(StdString(domainName + "_edge_y")); 1691 dimIdList.push_back(axisId + "_points"); 1692 field->setUseCompressedOutput(); 1634 1693 } 1635 1694 else 1636 { 1637 dimXid = "n" + domainName + "_face"; 1638 dimIdList.push_back(dimXid); 1639 dimCoordList.push_back(StdString(domainName + "_face_x")); 1640 dimCoordList.push_back(StdString(domainName + "_face_y")); 1641 } 1642 } // ugrid convention 1643 } // case unstructured domain 1644 } 1645 1646 if (domain->hasArea) 1647 { 1648 hasArea = true; 1649 cellMeasures += " area" + appendDomId; 1650 } 1651 ++idxDomain; 1652 } 1653 else if (1 == axisDomainOrder(i)) 1654 { 1655 CAxis* axis = CAxis::get(axisList[idxAxis]); 1656 StdString axisId = axis->getAxisOutputName(); 1657 1658 if (compressedOutput && axis->isCompressible()) 1659 { 1660 dimIdList.push_back(axisId + "_points"); 1661 field->setUseCompressedOutput(); 1662 } 1663 else 1664 dimIdList.push_back(axisId); 1665 1666 dimCoordList.push_back(axisId); 1667 ++idxAxis; 1668 } 1669 else // scalar 1670 { 1695 dimIdList.push_back(axisId); 1696 1697 dimCoordList.push_back(axisId); 1698 ++idxAxis; 1699 } 1700 else // scalar 1701 { 1671 1702 /* Do nothing here */ 1672 } 1673 } 1674 1675 /* 1676 StdString lonid_loc = (server->intraCommSize > 1) 1677 ? StdString("lon").append(appendDomid).append("_local") 1678 : lonid; 1679 StdString latid_loc = (server->intraCommSize > 1) 1680 ? StdString("lat").append(appendDomid).append("_local") 1681 : latid; 1682 */ 1683 StdString fieldid = field->getFieldOutputName(); 1684 1685 nc_type type ; 1686 if (field->prec.isEmpty()) type = NC_FLOAT ; 1687 else 1688 { 1689 if (field->prec==2) type = NC_SHORT ; 1690 else if (field->prec==4) type = NC_FLOAT ; 1691 else if (field->prec==8) type = NC_DOUBLE ; 1692 } 1693 1694 bool wtime = !(!field->operation.isEmpty() && field->getOperationTimeType() == func::CFunctor::once); 1695 1696 if (wtime) 1697 { 1698 1699 //StdOStringStream oss; 1700 // oss << "time_" << field->operation.getValue() 1701 // << "_" << field->getRelFile()->output_freq.getValue(); 1702 //oss 1703 if (field->getOperationTimeType() == func::CFunctor::instant) coodinates.push_back(string("time_instant")); 1704 else if (field->getOperationTimeType() == func::CFunctor::centered) coodinates.push_back(string("time_centered")); 1705 dims.push_back(timeid); 1706 } 1707 1708 if (compressedOutput && grid->isCompressible()) 1709 { 1710 dims.push_back(grid->getId() + "_points"); 1711 field->setUseCompressedOutput(); 1712 } 1713 else 1714 { 1715 while (!dimIdList.empty()) 1716 { 1717 dims.push_back(dimIdList.back()); 1718 dimIdList.pop_back(); 1719 } 1720 } 1721 1722 while (!dimCoordList.empty()) 1723 { 1724 coodinates.push_back(dimCoordList.back()); 1725 dimCoordList.pop_back(); 1726 } 1727 1728 try 1729 { 1703 } 1704 } 1705 1706 StdString fieldid = field->getFieldOutputName(); 1707 1708 nc_type type ; 1709 if (field->prec.isEmpty()) type = NC_FLOAT ; 1710 else 1711 { 1712 if (field->prec==2) type = NC_SHORT ; 1713 else if (field->prec==4) type = NC_FLOAT ; 1714 else if (field->prec==8) type = NC_DOUBLE ; 1715 } 1716 1717 bool wtime = !(!field->operation.isEmpty() && field->getOperationTimeType() == func::CFunctor::once); 1718 1719 if (wtime) 1720 { 1721 if (field->hasTimeInstant && hasTimeInstant) coodinates.push_back(string("time_instant")); 1722 else if (field->hasTimeCentered && hasTimeCentered) coodinates.push_back(string("time_centered")); 1723 dims.push_back(timeid); 1724 } 1725 1726 if (compressedOutput && grid->isCompressible()) 1727 { 1728 dims.push_back(grid->getId() + "_points"); 1729 field->setUseCompressedOutput(); 1730 } 1731 else 1732 { 1733 while (!dimIdList.empty()) 1734 { 1735 dims.push_back(dimIdList.back()); 1736 dimIdList.pop_back(); 1737 } 1738 } 1739 1740 while (!dimCoordList.empty()) 1741 { 1742 coodinates.push_back(dimCoordList.back()); 1743 dimCoordList.pop_back(); 1744 } 1745 1746 try 1747 { 1730 1748 SuperClassWriter::addVariable(fieldid, type, dims); 1731 1749 … … 1742 1760 ("units", field->unit.getValue(), &fieldid); 1743 1761 1744 if (!field->valid_min.isEmpty()) 1762 // Ugrid field attributes "mesh" and "location" 1763 if (!SuperClassWriter::useCFConvention) 1764 { 1765 if (!domainList.empty()) 1766 { 1767 CDomain* domain = CDomain::get(domainList[0]); // Suppose that we have only domain 1768 StdString mesh = domain->name; 1769 SuperClassWriter::addAttribute("mesh", mesh, &fieldid); 1770 StdString location; 1771 if (domain->nvertex == 1) 1772 location = "node"; 1773 else if (domain->nvertex == 2) 1774 location = "edge"; 1775 else if (domain->nvertex > 2) 1776 location = "face"; 1777 SuperClassWriter::addAttribute("location", location, &fieldid); 1778 } 1779 1780 } 1781 1782 if (!field->valid_min.isEmpty()) 1745 1783 SuperClassWriter::addAttribute 1746 1784 ("valid_min", field->valid_min.getValue(), &fieldid); … … 1771 1809 if (!field->cell_methods.isEmpty()) 1772 1810 { 1773 StdString cellMethodString = field->cell_methods;1774 if (field->cell_methods_mode.isEmpty() ||1811 StdString cellMethodString = field->cell_methods; 1812 if (field->cell_methods_mode.isEmpty() || 1775 1813 (CField::cell_methods_mode_attr::overwrite == field->cell_methods_mode)) 1776 {1777 SuperClassWriter::addAttribute("cell_methods", cellMethodString, &fieldid);1778 alreadyAddCellMethod = true;1779 }1780 else1781 {1782 switch (field->cell_methods_mode)1783 {1784 case (CField::cell_methods_mode_attr::prefix):1785 cellMethodsPrefix = cellMethodString;1786 cellMethodsPrefix += " ";1787 break;1788 case (CField::cell_methods_mode_attr::suffix):1789 cellMethodsSuffix = " ";1790 cellMethodsSuffix += cellMethodString;1791 break;1792 case (CField::cell_methods_mode_attr::none):1793 break;1794 default:1795 break;1796 }1797 }1814 { 1815 SuperClassWriter::addAttribute("cell_methods", cellMethodString, &fieldid); 1816 alreadyAddCellMethod = true; 1817 } 1818 else 1819 { 1820 switch (field->cell_methods_mode) 1821 { 1822 case (CField::cell_methods_mode_attr::prefix): 1823 cellMethodsPrefix = cellMethodString; 1824 cellMethodsPrefix += " "; 1825 break; 1826 case (CField::cell_methods_mode_attr::suffix): 1827 cellMethodsSuffix = " "; 1828 cellMethodsSuffix += cellMethodString; 1829 break; 1830 case (CField::cell_methods_mode_attr::none): 1831 break; 1832 default: 1833 break; 1834 } 1835 } 1798 1836 } 1799 1837 … … 1881 1919 singleDomain = (file->nbDomains == 1); 1882 1920 1921 StdString conv_str ; 1922 if (file->convention_str.isEmpty()) 1923 { 1924 if (SuperClassWriter::useCFConvention) conv_str="CF-1.6" ; 1925 else conv_str="UGRID" ; 1926 } 1927 else conv_str=file->convention_str ; 1928 1883 1929 try 1884 1930 { 1885 if (SuperClassWriter::useCFConvention) 1886 this->writeFileAttributes(filename, description, 1887 StdString("CF-1.5"), 1888 StdString("An IPSL model"), 1889 this->getTimeStamp()); 1890 else 1891 this->writeFileAttributes(filename, description, 1892 StdString("UGRID"), 1893 StdString("An IPSL model"), 1894 this->getTimeStamp()); 1895 1931 this->writeFileAttributes(filename, description, 1932 conv_str, 1933 StdString("An IPSL model"), 1934 this->getTimeStamp()); 1896 1935 1897 1936 if (!appendMode) … … 2017 2056 struct tm * timeinfo = NULL; 2018 2057 char buffer [buffer_size]; 2019 2058 StdString formatStr; 2059 if (file->time_stamp_format.isEmpty()) formatStr="%Y-%b-%d %H:%M:%S %Z" ; 2060 else formatStr=file->time_stamp_format; 2061 2062 // time ( &rawtime ); 2063 // timeinfo = localtime ( &rawtime ); 2020 2064 time ( &rawtime ); 2021 timeinfo = localtime ( &rawtime );2022 strftime (buffer, buffer_size, "%Y-%b-%d %H:%M:%S %Z", timeinfo);2065 timeinfo = gmtime ( &rawtime ); 2066 strftime (buffer, buffer_size, formatStr.c_str(), timeinfo); 2023 2067 2024 2068 return (StdString(buffer)); … … 2033 2077 CGrid* grid = field->grid; 2034 2078 2035 if (field->getNStep()<1) return ; 2079 if (field->getNStep()<1) 2080 { 2081 return; 2082 } 2036 2083 2037 2084 if (!grid->doGridHaveDataToWrite()) 2038 if (SuperClass::type == MULTI_FILE || !isCollective) return; 2085 if (SuperClass::type == MULTI_FILE || !isCollective) 2086 { 2087 return; 2088 } 2039 2089 2040 2090 StdString fieldid = field->getFieldOutputName(); … … 2042 2092 StdOStringStream oss; 2043 2093 string timeAxisId; 2044 if (field-> getOperationTimeType() == func::CFunctor::instant) timeAxisId = "time_instant";2045 else if (field-> getOperationTimeType() == func::CFunctor::centered) timeAxisId = "time_centered";2094 if (field->hasTimeInstant) timeAxisId = "time_instant"; 2095 else if (field->hasTimeCentered) timeAxisId = "time_centered"; 2046 2096 2047 2097 StdString timeBoundId = getTimeCounterName() + "_bounds"; 2048 2098 2049 2099 StdString timeAxisBoundId; 2050 if (field-> getOperationTimeType() == func::CFunctor::instant) timeAxisBoundId = "time_instant_bounds";2051 else if (field-> getOperationTimeType() == func::CFunctor::centered) timeAxisBoundId = "time_centered_bounds";2100 if (field->hasTimeInstant) timeAxisBoundId = "time_instant_bounds"; 2101 else if (field->hasTimeCentered) timeAxisBoundId = "time_centered_bounds"; 2052 2102 2053 2103 if (!field->wasWritten()) 2054 2104 { 2055 if (appendMode && field->file->record_offset.isEmpty() && 2056 2105 if (appendMode && field->file->record_offset.isEmpty() && 2106 field->getOperationTimeType() != func::CFunctor::once) 2057 2107 { 2058 field->resetNStep(getRecordFromTime(field->last_Write_srv) + 1); 2108 double factorUnit; 2109 if (!field->file->time_units.isEmpty() && field->file->time_units==CFile::time_units_attr::days) 2110 factorUnit=context->getCalendar()->getDayLengthInSeconds() ; 2111 else factorUnit=1 ; 2112 field->resetNStep(getRecordFromTime(field->last_Write_srv,factorUnit) + 1); 2059 2113 } 2060 2114 … … 2069 2123 2070 2124 bool wtime = (field->getOperationTimeType() != func::CFunctor::once); 2125 bool wtimeCounter =false ; 2126 bool wtimeData =false ; 2127 2071 2128 2072 2129 if (wtime) … … 2075 2132 Time lastLastWrite = field->lastlast_Write_srv; 2076 2133 2077 if (field->getOperationTimeType() == func::CFunctor::instant) 2078 time_data(0) = lastWrite; 2079 else if (field->getOperationTimeType() == func::CFunctor::centered) 2134 2135 if (field->hasTimeInstant) 2136 { 2137 time_data(0) = time_data_bound(1) = lastWrite; 2138 time_data_bound(0) = time_data_bound(1) = lastWrite; 2139 if (timeCounterType==instant) 2140 { 2141 time_counter(0) = time_data(0); 2142 time_counter_bound(0) = time_data_bound(0); 2143 time_counter_bound(1) = time_data_bound(1); 2144 wtimeCounter=true ; 2145 } 2146 if (hasTimeInstant) wtimeData=true ; 2147 } 2148 else if (field->hasTimeCentered) 2149 { 2080 2150 time_data(0) = (lastWrite + lastLastWrite) / 2; 2081 2082 if (field->getOperationTimeType() == func::CFunctor::instant)2083 time_data_bound(0) = time_data_bound(1) = lastWrite;2084 else if (field->getOperationTimeType() == func::CFunctor::centered)2085 {2086 2151 time_data_bound(0) = lastLastWrite; 2087 2152 time_data_bound(1) = lastWrite; 2153 if (timeCounterType==centered) 2154 { 2155 time_counter(0) = time_data(0) ; 2156 time_counter_bound(0) = time_data_bound(0) ; 2157 time_counter_bound(1) = time_data_bound(1) ; 2158 wtimeCounter=true ; 2159 } 2160 if (hasTimeCentered) wtimeData=true ; 2088 2161 } 2089 2162 2090 if (field->file->time_counter == CFile::time_counter_attr::instant) 2091 time_counter(0) = lastWrite; 2092 else if (field->file->time_counter == CFile::time_counter_attr::centered) 2093 time_counter(0) = (lastWrite + lastLastWrite) / 2; 2094 else if (field->file->time_counter == CFile::time_counter_attr::record) 2163 if (timeCounterType==record) 2164 { 2095 2165 time_counter(0) = field->getNStep() - 1; 2096 2097 2098 if (field->file->time_counter == CFile::time_counter_attr::instant)2099 time_counter_bound(0) = time_counter_bound(1) = lastWrite; 2100 else if (field->file->time_counter == CFile::time_counter_attr::centered)2166 time_counter_bound(0) = time_counter_bound(1) = field->getNStep() - 1; 2167 wtimeCounter=true ; 2168 } 2169 2170 if (!field->file->time_units.isEmpty() && field->file->time_units==CFile::time_units_attr::days) 2101 2171 { 2102 time_counter_bound(0) = lastLastWrite; 2103 time_counter_bound(1) = lastWrite; 2172 double secByDay=context->getCalendar()->getDayLengthInSeconds() ; 2173 time_data/=secByDay; 2174 time_data_bound/=secByDay; 2175 time_counter/=secByDay; 2176 time_counter_bound/=secByDay; 2104 2177 } 2105 else if (field->file->time_counter == CFile::time_counter_attr::record)2106 time_counter_bound(0) = time_counter_bound(1) = field->getNStep() - 1;2107 2178 } 2108 2179 … … 2140 2211 case (MULTI_FILE) : 2141 2212 { 2213 CTimer::get("Files : writing data").resume(); 2142 2214 SuperClassWriter::writeData(fieldData, fieldid, isCollective, field->getNStep() - 1); 2215 CTimer::get("Files : writing data").suspend(); 2143 2216 if (wtime) 2144 2217 { 2145 SuperClassWriter::writeData(time_data, timeAxisId, isCollective, field->getNStep() - 1); 2146 SuperClassWriter::writeData(time_data_bound, timeAxisBoundId, isCollective, field->getNStep() - 1); 2147 if (field->file->time_counter != CFile::time_counter_attr::none) 2218 CTimer::get("Files : writing time axis").resume(); 2219 if ( wtimeData) 2148 2220 { 2149 SuperClassWriter::writeData(time_counter, getTimeCounterName(), isCollective, field->getNStep() - 1); 2150 if (field->file->time_counter != CFile::time_counter_attr::record) 2151 SuperClassWriter::writeData(time_counter_bound, timeBoundId, isCollective, field->getNStep() - 1); 2221 // SuperClassWriter::writeData(time_data, timeAxisId, isCollective, field->getNStep() - 1); 2222 // SuperClassWriter::writeData(time_data_bound, timeAxisBoundId, isCollective, field->getNStep() - 1); 2223 SuperClassWriter::writeTimeAxisData(time_data, timeAxisId, isCollective, field->getNStep() - 1, isRoot); 2224 SuperClassWriter::writeTimeAxisDataBounds(time_data_bound, timeAxisBoundId, isCollective, field->getNStep() - 1, isRoot); 2225 } 2226 if (wtimeCounter) 2227 { 2228 // SuperClassWriter::writeData(time_counter, getTimeCounterName(), isCollective, field->getNStep() - 1); 2229 // if (timeCounterType!=record) SuperClassWriter::writeData(time_counter_bound, timeBoundId, isCollective, field->getNStep() - 1); 2230 SuperClassWriter::writeTimeAxisData(time_counter, getTimeCounterName(), isCollective, field->getNStep() - 1,isRoot); 2231 if (timeCounterType!=record) SuperClassWriter::writeTimeAxisDataBounds(time_counter_bound, timeBoundId, isCollective, field->getNStep() - 1, isRoot); 2152 2232 } 2233 CTimer::get("Files : writing time axis").suspend(); 2153 2234 } 2154 2235 break; … … 2227 2308 } 2228 2309 } 2229 } 2310 } 2230 2311 } 2231 2312 else … … 2278 2359 } 2279 2360 2361 2362 CTimer::get("Files : writing data").resume(); 2280 2363 SuperClassWriter::writeData(fieldData, fieldid, isCollective, field->getNStep() - 1, &start, &count); 2281 if (wtime) 2282 { 2283 SuperClassWriter::writeTimeAxisData(time_data, timeAxisId, isCollective, field->getNStep() - 1, isRoot); 2284 SuperClassWriter::writeTimeAxisData(time_data_bound, timeAxisBoundId, isCollective, field->getNStep() - 1, isRoot); 2285 if (field->file->time_counter != CFile::time_counter_attr::none) 2364 CTimer::get("Files : writing data").suspend(); 2365 2366 if (wtime) 2367 { 2368 CTimer::get("Files : writing time axis").resume(); 2369 if ( wtimeData) 2286 2370 { 2287 SuperClassWriter::writeTimeAxisData(time_counter, getTimeCounterName(), isCollective, field->getNStep() - 1, isRoot); 2288 if (field->file->time_counter != CFile::time_counter_attr::record) 2289 SuperClassWriter::writeTimeAxisData(time_counter_bound, timeBoundId, isCollective, field->getNStep() - 1, isRoot); 2371 // SuperClassWriter::writeData(time_data, timeAxisId, isCollective, field->getNStep() - 1); 2372 // SuperClassWriter::writeData(time_data_bound, timeAxisBoundId, isCollective, field->getNStep() - 1); 2373 SuperClassWriter::writeTimeAxisData(time_data, timeAxisId, isCollective, field->getNStep() - 1, isRoot); 2374 SuperClassWriter::writeTimeAxisDataBounds(time_data_bound, timeAxisBoundId, isCollective, field->getNStep() - 1, isRoot); 2290 2375 } 2291 } 2376 if (wtimeCounter) 2377 { 2378 // SuperClassWriter::writeData(time_counter, getTimeCounterName(), isCollective, field->getNStep() - 1); 2379 // if (timeCounterType!=record) SuperClassWriter::writeData(time_counter_bound, timeBoundId, isCollective, field->getNStep() - 1); 2380 SuperClassWriter::writeTimeAxisData(time_counter, getTimeCounterName(), isCollective, field->getNStep() - 1,isRoot); 2381 if (timeCounterType!=record) SuperClassWriter::writeTimeAxisDataBounds(time_counter_bound, timeBoundId, isCollective, field->getNStep() - 1, isRoot); 2382 2383 } 2384 CTimer::get("Files : writing time axis").suspend(); 2385 } 2292 2386 2293 2387 break; … … 2313 2407 { 2314 2408 StdOStringStream oss; 2315 2409 bool createInstantAxis=false ; 2410 bool createCenteredAxis=false ; 2411 bool createTimeCounterAxis=false ; 2412 2316 2413 if (field->getOperationTimeType() == func::CFunctor::once) return ; 2317 2414 2318 // oss << "time_" << field->operation.getValue() 2319 // << "_" << field->getRelFile()->output_freq.getValue(); 2320 2321 // StdString axisid = oss.str(); 2322 // if (field->getOperationTimeType() == func::CFunctor::centered) axisid="time_centered" ; 2323 // else if (field->getOperationTimeType() == func::CFunctor::instant) axisid="time_instant" ; 2324 2325 StdString axisid("time_centered") ; 2326 StdString axisBoundId("time_centered_bounds"); 2415 2416 StdString axisId ; 2417 StdString axisBoundId; 2327 2418 StdString timeid(getTimeCounterName()); 2328 2419 StdString timeBoundId("axis_nbounds"); 2329 2420 2330 if (field->getOperationTimeType() == func::CFunctor::instant) 2331 { 2332 axisid = "time_instant"; 2333 axisBoundId = "time_instant_bounds"; 2334 } 2335 2421 StdString strTimeUnits ; 2422 if (!field->file->time_units.isEmpty() && field->file->time_units==CFile::time_units_attr::days) strTimeUnits="days since " ; 2423 else strTimeUnits="seconds since " ; 2424 2425 if (field->getOperationTimeType() == func::CFunctor::instant) field->hasTimeInstant = true; 2426 if (field->getOperationTimeType() == func::CFunctor::centered) field->hasTimeCentered = true; 2427 2428 2429 if (field->file->time_counter.isEmpty()) 2430 { 2431 if (timeCounterType==none) createTimeCounterAxis=true ; 2432 if (field->hasTimeCentered) 2433 { 2434 timeCounterType=centered ; 2435 if (!hasTimeCentered) createCenteredAxis=true ; 2436 } 2437 if (field->hasTimeInstant) 2438 { 2439 if (timeCounterType==none) timeCounterType=instant ; 2440 if (!hasTimeInstant) createInstantAxis=true ; 2441 } 2442 } 2443 else if (field->file->time_counter==CFile::time_counter_attr::instant) 2444 { 2445 if (field->hasTimeCentered) 2446 { 2447 if (!hasTimeCentered) createCenteredAxis=true ; 2448 } 2449 if (field->hasTimeInstant) 2450 { 2451 if (timeCounterType==none) createTimeCounterAxis=true ; 2452 timeCounterType=instant ; 2453 if (!hasTimeInstant) createInstantAxis=true ; 2454 } 2455 } 2456 else if (field->file->time_counter==CFile::time_counter_attr::centered) 2457 { 2458 if (field->hasTimeCentered) 2459 { 2460 if (timeCounterType==none) createTimeCounterAxis=true ; 2461 timeCounterType=centered ; 2462 if (!hasTimeCentered) createCenteredAxis=true ; 2463 } 2464 if (field->hasTimeInstant) 2465 { 2466 if (!hasTimeInstant) createInstantAxis=true ; 2467 } 2468 } 2469 else if (field->file->time_counter==CFile::time_counter_attr::instant_exclusive) 2470 { 2471 if (field->hasTimeCentered) 2472 { 2473 if (!hasTimeCentered) createCenteredAxis=true ; 2474 } 2475 if (field->hasTimeInstant) 2476 { 2477 if (timeCounterType==none) createTimeCounterAxis=true ; 2478 timeCounterType=instant ; 2479 } 2480 } 2481 else if (field->file->time_counter==CFile::time_counter_attr::centered_exclusive) 2482 { 2483 if (field->hasTimeCentered) 2484 { 2485 if (timeCounterType==none) createTimeCounterAxis=true ; 2486 timeCounterType=centered ; 2487 } 2488 if (field->hasTimeInstant) 2489 { 2490 if (!hasTimeInstant) createInstantAxis=true ; 2491 } 2492 } 2493 else if (field->file->time_counter==CFile::time_counter_attr::exclusive) 2494 { 2495 if (field->hasTimeCentered) 2496 { 2497 if (timeCounterType==none) createTimeCounterAxis=true ; 2498 if (timeCounterType==instant) createInstantAxis=true ; 2499 timeCounterType=centered ; 2500 } 2501 if (field->hasTimeInstant) 2502 { 2503 if (timeCounterType==none) 2504 { 2505 createTimeCounterAxis=true ; 2506 timeCounterType=instant ; 2507 } 2508 if (timeCounterType==centered) 2509 { 2510 if (!hasTimeInstant) createInstantAxis=true ; 2511 } 2512 } 2513 } 2514 else if (field->file->time_counter==CFile::time_counter_attr::none) 2515 { 2516 if (field->hasTimeCentered) 2517 { 2518 if (!hasTimeCentered) createCenteredAxis=true ; 2519 } 2520 if (field->hasTimeInstant) 2521 { 2522 if (!hasTimeInstant) createInstantAxis=true ; 2523 } 2524 } 2525 else if (field->file->time_counter==CFile::time_counter_attr::record) 2526 { 2527 if (timeCounterType==none) createTimeCounterAxis=true ; 2528 timeCounterType=record ; 2529 if (field->hasTimeCentered) 2530 { 2531 if (!hasTimeCentered) createCenteredAxis=true ; 2532 } 2533 if (field->hasTimeInstant) 2534 { 2535 if (!hasTimeInstant) createInstantAxis=true ; 2536 } 2537 } 2538 2539 if (createInstantAxis) 2540 { 2541 axisId="time_instant" ; 2542 axisBoundId="time_instant_bounds"; 2543 hasTimeInstant=true ; 2544 } 2545 2546 if (createCenteredAxis) 2547 { 2548 axisId="time_centered" ; 2549 axisBoundId="time_centered_bounds"; 2550 hasTimeCentered=true ; 2551 } 2552 2553 2336 2554 try 2337 2555 { 2338 // Adding time_instant or time_centered 2339 std::vector<StdString> dims; 2340 dims.push_back(timeid); 2341 if (!SuperClassWriter::varExist(axisid)) 2342 { 2343 SuperClassWriter::addVariable(axisid, NC_DOUBLE, dims); 2344 2345 CDate timeOrigin=cal->getTimeOrigin() ; 2346 StdOStringStream oss2; 2347 // oss2<<initDate.getYear()<<"-"<<initDate.getMonth()<<"-"<<initDate.getDay()<<" " 2348 // <<initDate.getHour()<<"-"<<initDate.getMinute()<<"-"<<initDate.getSecond() ; 2349 StdString strInitdate=oss2.str() ; 2350 StdString strTimeOrigin=timeOrigin.toString() ; 2351 this->writeTimeAxisAttributes 2352 (axisid, cal->getType(), 2353 StdString("seconds since ").append(strTimeOrigin), 2354 strTimeOrigin, axisBoundId); 2355 } 2356 2357 // Adding time_instant_bounds or time_centered_bounds variables 2358 if (!SuperClassWriter::varExist(axisBoundId)) 2359 { 2360 dims.clear() ; 2556 std::vector<StdString> dims; 2557 2558 if (createInstantAxis || createCenteredAxis) 2559 { 2560 // Adding time_instant or time_centered 2361 2561 dims.push_back(timeid); 2362 dims.push_back(timeBoundId); 2363 SuperClassWriter::addVariable(axisBoundId, NC_DOUBLE, dims); 2364 } 2365 2366 if (field->file->time_counter != CFile::time_counter_attr::none) 2562 if (!SuperClassWriter::varExist(axisId)) 2563 { 2564 SuperClassWriter::addVariable(axisId, NC_DOUBLE, dims); 2565 2566 CDate timeOrigin=cal->getTimeOrigin() ; 2567 StdOStringStream oss2; 2568 StdString strInitdate=oss2.str() ; 2569 StdString strTimeOrigin=timeOrigin.toString() ; 2570 this->writeTimeAxisAttributes(axisId, cal->getType(),strTimeUnits+strTimeOrigin, 2571 strTimeOrigin, axisBoundId); 2572 } 2573 2574 // Adding time_instant_bounds or time_centered_bounds variables 2575 if (!SuperClassWriter::varExist(axisBoundId)) 2576 { 2577 dims.clear() ; 2578 dims.push_back(timeid); 2579 dims.push_back(timeBoundId); 2580 SuperClassWriter::addVariable(axisBoundId, NC_DOUBLE, dims); 2581 } 2582 } 2583 2584 if (createTimeCounterAxis) 2367 2585 { 2368 2586 // Adding time_counter 2369 axis id = getTimeCounterName();2587 axisId = getTimeCounterName(); 2370 2588 axisBoundId = getTimeCounterName() + "_bounds"; 2371 2589 dims.clear(); 2372 2590 dims.push_back(timeid); 2373 if (!SuperClassWriter::varExist(axis id))2591 if (!SuperClassWriter::varExist(axisId)) 2374 2592 { 2375 SuperClassWriter::addVariable(axisid, NC_DOUBLE, dims); 2376 SuperClassWriter::addAttribute("axis", string("T"), &axisid); 2377 2378 if (field->file->time_counter != CFile::time_counter_attr::record) 2593 SuperClassWriter::addVariable(axisId, NC_DOUBLE, dims); 2594 SuperClassWriter::addAttribute("axis", string("T"), &axisId); 2595 2596 if (field->file->time_counter.isEmpty() || 2597 (field->file->time_counter != CFile::time_counter_attr::record)) 2379 2598 { 2380 2599 CDate timeOrigin = cal->getTimeOrigin(); 2381 2600 StdString strTimeOrigin = timeOrigin.toString(); 2382 2601 2383 this->writeTimeAxisAttributes(axis id, cal->getType(),2384 StdString("seconds since ").append(strTimeOrigin),2602 this->writeTimeAxisAttributes(axisId, cal->getType(), 2603 strTimeUnits+strTimeOrigin, 2385 2604 strTimeOrigin, axisBoundId); 2386 2605 } … … 2388 2607 2389 2608 // Adding time_counter_bound dimension 2390 if (field->file->time_counter != CFile::time_counter_attr::record)2609 if (field->file->time_counter.isEmpty() || (field->file->time_counter != CFile::time_counter_attr::record)) 2391 2610 { 2392 2611 if (!SuperClassWriter::varExist(axisBoundId)) … … 2563 2782 SuperClassWriter::addAttribute("title" , description); 2564 2783 SuperClassWriter::addAttribute("Conventions", conventions); 2565 SuperClassWriter::addAttribute("production" , production); 2566 SuperClassWriter::addAttribute("timeStamp" , timeStamp); 2784 // SuperClassWriter::addAttribute("production" , production); 2785 2786 StdString timeStampStr ; 2787 if (file->time_stamp_name.isEmpty()) timeStampStr="timeStamp" ; 2788 else timeStampStr=file->time_stamp_name ; 2789 SuperClassWriter::addAttribute(timeStampStr, timeStamp); 2790 2791 StdString uuidName ; 2792 if (file->uuid_name.isEmpty()) uuidName="uuid" ; 2793 else uuidName=file->uuid_name ; 2794 2795 if (file->uuid_format.isEmpty()) SuperClassWriter::addAttribute(uuidName, getUuidStr()); 2796 else SuperClassWriter::addAttribute(uuidName, getUuidStr(file->uuid_format)); 2797 2567 2798 } 2568 2799 catch (CNetCdfException& e) … … 2616 2847 ///-------------------------------------------------------------- 2617 2848 2618 StdSize CNc4DataOutput::getRecordFromTime(Time time )2849 StdSize CNc4DataOutput::getRecordFromTime(Time time, double factorUnit) 2619 2850 { 2620 2851 std::map<Time, StdSize>::const_iterator it = timeToRecordCache.find(time); … … 2622 2853 { 2623 2854 StdString timeAxisBoundsId(getTimeCounterName() + "_bounds"); 2624 if (!SuperClassWriter::varExist(timeAxisBoundsId)) 2625 2855 if (!SuperClassWriter::varExist(timeAxisBoundsId)) timeAxisBoundsId = "time_centered_bounds"; 2856 if (!SuperClassWriter::varExist(timeAxisBoundsId)) timeAxisBoundsId = "time_instant_bounds"; 2626 2857 2627 2858 CArray<double,2> timeAxisBounds; 2628 SuperClassWriter::getTimeAxisBounds(timeAxisBounds, timeAxisBoundsId, isCollective);2629 2859 std::vector<StdSize> dimSize(SuperClassWriter::getDimensions(timeAxisBoundsId)) ; 2860 2630 2861 StdSize record = 0; 2631 2862 double dtime(time); 2632 for (int n = timeAxisBounds.extent(1)- 1; n >= 0; n--)2863 for (int n = dimSize[0] - 1; n >= 0; n--) 2633 2864 { 2634 if (timeAxisBounds(1, n) < dtime) 2865 SuperClassWriter::getTimeAxisBounds(timeAxisBounds, timeAxisBoundsId, isCollective, n); 2866 timeAxisBounds*=factorUnit ; 2867 if (timeAxisBounds(1, 0) < dtime) 2635 2868 { 2636 2869 record = n + 1; -
XIOS/dev/dev_olga/src/io/nc4_data_output.hpp
r887 r1158 23 23 /// Constructeurs /// 24 24 CNc4DataOutput 25 ( const StdString & filename, bool exist);25 (CFile* file, const StdString & filename, bool exist); 26 26 CNc4DataOutput 27 ( const StdString & filename, bool exist, bool useClassicFormat,27 (CFile* file, const StdString & filename, bool exist, bool useClassicFormat, 28 28 bool useCFConvention, 29 29 MPI_Comm comm_file, bool multifile, bool isCollective = true, … … 96 96 const StdString & nav_model); 97 97 98 StdSize getRecordFromTime(Time time );98 StdSize getRecordFromTime(Time time, double factorUnit); 99 99 100 100 private : … … 123 123 std::set<std::string> writtenAxis, writtenCompressedAxis; 124 124 std::set<std::string> writtenScalar; 125 126 enum { none, centered, instant, record} timeCounterType ; 127 bool hasTimeInstant ; 128 bool hasTimeCentered ; 125 129 }; // class CNc4DataOutput 126 130 -
XIOS/dev/dev_olga/src/io/netCdfInterface.cpp
r972 r1158 967 967 } 968 968 969 template<> 970 int CNetCdfInterface::ncGetVaraType(int ncid, int varid, const StdSize* start, const StdSize* count, char* data) 971 { 972 return nc_get_vara_text(ncid, varid, start, count, data); 973 } 974 969 975 // Some specializations of putVariableType 970 976 template<> … … 984 990 { 985 991 return nc_put_vara_int(ncid, varid, start, count, data); 992 } 993 994 template<> 995 int CNetCdfInterface::ncPutVaraType(int ncid, int varid, const StdSize* start, const StdSize* count, const char* data) 996 { 997 return nc_put_vara_text(ncid, varid, start, count, data); 986 998 } 987 999 -
XIOS/dev/dev_olga/src/io/netCdfInterface_decl.cpp
r686 r1158 33 33 macroPutVar(float) 34 34 macroPutVar(int) 35 35 macroPutVar(char) 36 36 37 #define macroType(type, ncType) \ 37 38 template<> nc_type CNetCdfInterface::getNcType<type>() { return ncType; } -
XIOS/dev/dev_olga/src/io/netCdfInterface_impl.hpp
r1030 r1158 121 121 inqVarName(ncid, varId, varName); 122 122 sstr << "Unable to write data given the location id: " << ncid << " and the variable whose id: " << varId << " and name: " << varName << std::endl; 123 // if (status == NC_ENOTVAR )124 // sstr << "Variable not found. "<< std::endl;125 // else if (status == NC_EINVALCOORDS)126 // sstr << "Index exceeds dimension bound. "<< std::endl;127 // else if (status == NC_EEDGE)128 // sstr << " Start+count exceeds dimension bound. "<< std::endl;129 // else if (status == NC_ERANGE)130 // sstr << " One or more of the values are out of range. "<< std::endl;131 // else if (status == NC_EINDEFINE)132 // sstr << " Operation not allowed in define mode. "<< std::endl;133 // else if (status == NC_EBADID)134 // sstr << "Bad ncid. "<< std::endl;135 123 throw CNetCdfException(sstr.str()); 136 124 } -
XIOS/dev/dev_olga/src/io/onetcdf4.cpp
r878 r1158 7 7 #include "netCdfInterface.hpp" 8 8 #include "netCdfException.hpp" 9 #include "timer.hpp" 9 10 10 11 namespace xios … … 55 56 if (!append || !std::ifstream(filename.c_str())) 56 57 { 58 CTimer::get("Files : create").resume(); 57 59 if (wmpi) 58 60 CNetCdfInterface::createPar(filename, mode, *comm, MPI_INFO_NULL, this->ncidp); 59 61 else 60 62 CNetCdfInterface::create(filename, mode, this->ncidp); 61 63 CTimer::get("Files : create").suspend(); 64 62 65 this->appendMode = false; 63 66 } … … 65 68 { 66 69 mode |= NC_WRITE; 70 CTimer::get("Files : open").resume(); 67 71 if (wmpi) 68 72 CNetCdfInterface::openPar(filename, mode, *comm, MPI_INFO_NULL, this->ncidp); 69 73 else 70 74 CNetCdfInterface::open(filename, mode, this->ncidp); 71 75 CTimer::get("Files : open").suspend(); 72 76 this->appendMode = true; 73 77 } … … 83 87 void CONetCDF4::close() 84 88 { 89 CTimer::get("Files : close").resume(); 85 90 CNetCdfInterface::close(this->ncidp); 91 CTimer::get("Files : close").suspend(); 86 92 } 87 93 … … 247 253 } 248 254 249 //--------------------------------------------------------------- 255 void CONetCDF4::getTimeAxisBounds(CArray<double,2>& timeAxisBounds, const StdString& name, bool collective, size_t record) 256 { 257 int grpid = this->getCurrentGroup(); 258 int varid = this->getVariable(name); 259 260 std::vector<StdSize> start(2), count(2); 261 start[0] = record; 262 count[0] = 1 ; 263 start[1] = 0; 264 count[1] = 2; 265 266 timeAxisBounds.resize(2, 1); 267 268 if (this->wmpi && collective) 269 CNetCdfInterface::varParAccess(grpid, varid, NC_COLLECTIVE); 270 if (this->wmpi && !collective) 271 CNetCdfInterface::varParAccess(grpid, varid, NC_INDEPENDENT); 272 273 CNetCdfInterface::getVaraType(grpid, varid, &start[0], &count[0], timeAxisBounds.dataFirst()); 274 } 275 276 250 277 251 278 const CONetCDF4::CONetCDF4Path& CONetCDF4::getCurrentPath(void) const … … 503 530 void CONetCDF4::writeData_(int grpid, int varid, 504 531 const std::vector<StdSize>& sstart, 532 const std::vector<StdSize>& scount, char* data) 533 { 534 CNetCdfInterface::putVaraType(grpid, varid, &sstart[0], &scount[0], data); 535 } 536 537 template <> 538 void CONetCDF4::writeData_(int grpid, int varid, 539 const std::vector<StdSize>& sstart, 505 540 const std::vector<StdSize>& scount, const int* data) 506 541 { 507 542 CNetCdfInterface::putVaraType(grpid, varid, &sstart[0], &scount[0], data); 508 543 } 509 510 544 //--------------------------------------------------------------- 511 545 … … 528 562 529 563 this->getWriteDataInfos(name, 0, array_size, sstart, scount, NULL, NULL); 564 530 565 this->writeData_(grpid, varid, sstart, scount, data.dataFirst()); 566 531 567 } 532 568 … … 554 590 555 591 this->getWriteDataInfos(name, record, array_size, sstart, scount, NULL, NULL); 556 if (using_netcdf_internal)557 {558 if (!isRoot)559 {560 sstart[0] = sstart[0] + 1;561 scount[0] = 0;562 }563 }564 592 this->writeData_(grpid, varid, sstart, scount, data.dataFirst()); 565 593 } 566 594 595 void CONetCDF4::writeTimeAxisDataBounds(const CArray<double, 1>& data, const StdString& name, 596 bool collective, StdSize record, bool isRoot) 597 { 598 int grpid = this->getCurrentGroup(); 599 int varid = this->getVariable(name); 600 601 map<int,size_t>::iterator it=timeAxis.find(varid); 602 if (it == timeAxis.end()) timeAxis[varid] = record; 603 else 604 { 605 if (it->second >= record) return; 606 else it->second =record; 607 } 608 609 StdSize array_size = 1; 610 std::vector<StdSize> sstart, scount; 611 612 if (this->wmpi && collective) 613 CNetCdfInterface::varParAccess(grpid, varid, NC_COLLECTIVE); 614 if (this->wmpi && !collective) 615 CNetCdfInterface::varParAccess(grpid, varid, NC_INDEPENDENT); 616 617 this->getWriteDataInfos(name, record, array_size, sstart, scount, NULL, NULL); 618 this->writeData_(grpid, varid, sstart, scount, data.dataFirst()); 619 } 620 621 567 622 //--------------------------------------------------------------- 568 623 -
XIOS/dev/dev_olga/src/io/onetcdf4.hpp
r878 r1158 71 71 void writeTimeAxisData(const CArray<double,1>& data, const StdString& name, 72 72 bool collective, StdSize record, bool Isroot); 73 void writeTimeAxisDataBounds(const CArray<double,1>& data, const StdString& name, 74 bool collective, StdSize record, bool Isroot); 73 75 /// Accesseur /// 74 76 const CONetCDF4Path& getCurrentPath(void) const; … … 97 99 const StdString& getTimeCounterName(void) const { return timeCounterName; }; 98 100 99 void getTimeAxisBounds(CArray<double,2>& timeAxisBounds, const StdString& name, bool collective); 101 void getTimeAxisBounds(CArray<double,2>& timeAxisBounds, const StdString& name, bool collective ); 102 void getTimeAxisBounds(CArray<double,2>& timeAxisBounds, const StdString& name, bool collective, size_t record); 100 103 101 104 bool varExist(const StdString& varname); -
XIOS/dev/dev_olga/src/io/onetcdf4_decl.cpp
r924 r1158 14 14 macro(double, 2) 15 15 macro(double, 3) 16 macro(StdString, 1) 16 17 17 18 template void CONetCDF4::setDefaultValue<double>(const StdString & varname, const double* value) ; -
XIOS/dev/dev_olga/src/io/onetcdf4_impl.hpp
r685 r1158 4 4 #include "onetcdf4.hpp" 5 5 #include "netCdfInterface.hpp" 6 #include "timer.hpp" 6 7 7 8 namespace xios … … 23 24 CNetCdfInterface::varParAccess(grpid, varid, NC_INDEPENDENT); 24 25 26 CTimer::get("Files : get data infos").resume(); 25 27 this->getWriteDataInfos 26 28 (name, record, array_size, sstart, scount, start, count); 29 CTimer::get("Files : get data infos").suspend(); 30 27 31 if (data.numElements() != array_size) 28 32 { … … 34 38 35 39 this->writeData_(grpid, varid, sstart, scount, data.dataFirst()); 40 } 41 42 template <> 43 void CONetCDF4::writeData(const CArray<StdString, 1>& data, const StdString & name, 44 bool collective, StdSize record, 45 const std::vector<StdSize> * start, 46 const std::vector<StdSize> * count) 47 { 48 int grpid = this->getCurrentGroup(); 49 int varid = this->getVariable(name); 50 StdSize array_size = 1; 51 std::vector<StdSize> sstart, scount; 52 53 if (this->wmpi && collective) 54 CNetCdfInterface::varParAccess(grpid, varid, NC_COLLECTIVE); 55 if (this->wmpi && !collective) 56 CNetCdfInterface::varParAccess(grpid, varid, NC_INDEPENDENT); 57 58 CTimer::get("CONetCDF4::writeData getWriteDataInfos").resume(); 59 this->getWriteDataInfos(name, record, array_size, sstart, scount, start, count); 60 CTimer::get("CONetCDF4::writeData getWriteDataInfos").suspend(); 61 62 if (data.numElements()*stringArrayLen != array_size) 63 { 64 ERROR("CONetCDF4::writeData(...)", 65 << "[ input array size = " << data.numElements() 66 << ", intern array size = " << array_size 67 << " ] Invalid input data !" ); 68 } 69 char* ArrayStr ; 70 char *PtrArrayStr ; 71 PtrArrayStr=ArrayStr=new char[data.numElements()*stringArrayLen] ; 72 Array<StdString,1>::const_iterator it, itb=data.begin(), ite=data.end() ; 73 for(it=itb;it!=ite;++it,PtrArrayStr+=stringArrayLen) 74 { 75 it->copy(PtrArrayStr,it->size()) ; 76 PtrArrayStr[it->size()]='\0' ; 77 } 78 CTimer::get("CONetCDF4::writeData writeData_").resume(); 79 this->writeData_(grpid, varid, sstart, scount, ArrayStr); 80 CTimer::get("CONetCDF4::writeData writeData_").suspend(); 81 delete [] ArrayStr ; 36 82 } 37 83
Note: See TracChangeset
for help on using the changeset viewer.