Changeset 1037 for XIOS/dev/branch_yushan/src/io/nc4_data_output.cpp
- Timestamp:
- 01/25/17 16:25:17 (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
XIOS/dev/branch_yushan/src/io/nc4_data_output.cpp
r1012 r1037 21 21 , filename(filename) 22 22 { 23 23 SuperClass::type = MULTI_FILE; 24 24 } 25 25 … … 33 33 , isCollective(isCollective) 34 34 { 35 35 SuperClass::type = (multifile) ? MULTI_FILE : ONE_FILE; 36 36 } 37 37 … … 1458 1458 void CNc4DataOutput::writeField_(CField* field) 1459 1459 { 1460 CContext* context = CContext::getCurrent() ;1461 CContextServer* server=context->server ;1462 1463 std::vector<StdString> dims, coodinates;1464 CGrid* grid = field->grid;1465 if (!grid->doGridHaveDataToWrite())1460 CContext* context = CContext::getCurrent() ; 1461 CContextServer* server=context->server ; 1462 1463 std::vector<StdString> dims, coodinates; 1464 CGrid* grid = field->grid; 1465 if (!grid->doGridHaveDataToWrite()) 1466 1466 if (SuperClass::type==MULTI_FILE) return ; 1467 1467 1468 CArray<int,1> axisDomainOrder = grid->axis_domain_order; 1469 int numElement = axisDomainOrder.numElements(), idxDomain = 0, idxAxis = 0, idxScalar = 0; 1470 std::vector<StdString> domainList = grid->getDomainList(); 1471 std::vector<StdString> axisList = grid->getAxisList(); 1472 std::vector<StdString> scalarList = grid->getScalarList(); 1473 1474 StdString timeid = getTimeCounterName(); 1475 StdString dimXid,dimYid; 1476 std::deque<StdString> dimIdList, dimCoordList; 1477 bool hasArea = false; 1478 StdString cellMeasures = "area:"; 1479 bool compressedOutput = !field->indexed_output.isEmpty() && field->indexed_output; 1480 1481 for (int i = 0; i < numElement; ++i) 1482 { 1483 if (2 == axisDomainOrder(i)) 1484 { 1485 CDomain* domain = CDomain::get(domainList[idxDomain]); 1486 StdString domId = domain->getDomainOutputName(); 1487 StdString appendDomId = singleDomain ? "" : "_" + domId ; 1488 1489 if (compressedOutput && domain->isCompressible() && domain->type != CDomain::type_attr::unstructured) 1468 CArray<int,1> axisDomainOrder = grid->axis_domain_order; 1469 int numElement = axisDomainOrder.numElements(), idxDomain = 0, idxAxis = 0, idxScalar = 0; 1470 std::vector<StdString> domainList = grid->getDomainList(); 1471 std::vector<StdString> axisList = grid->getAxisList(); 1472 std::vector<StdString> scalarList = grid->getScalarList(); 1473 1474 StdString timeid = getTimeCounterName(); 1475 StdString dimXid,dimYid; 1476 std::deque<StdString> dimIdList, dimCoordList; 1477 bool hasArea = false; 1478 StdString cellMeasures = "area:"; 1479 bool compressedOutput = !field->indexed_output.isEmpty() && field->indexed_output; 1480 1481 for (int i = 0; i < numElement; ++i) 1482 { 1483 if (2 == axisDomainOrder(i)) 1484 { 1485 CDomain* domain = CDomain::get(domainList[idxDomain]); 1486 StdString domId = domain->getDomainOutputName(); 1487 StdString appendDomId = singleDomain ? "" : "_" + domId ; 1488 1489 if (compressedOutput && domain->isCompressible() && domain->type != CDomain::type_attr::unstructured) 1490 { 1491 dimIdList.push_back(domId + "_points"); 1492 field->setUseCompressedOutput(); 1493 } 1494 1495 switch (domain->type) 1496 { 1497 case CDomain::type_attr::curvilinear: 1498 if (!compressedOutput || !domain->isCompressible()) 1499 { 1500 dimXid = StdString("x").append(appendDomId); 1501 dimIdList.push_back(dimXid); 1502 dimYid = StdString("y").append(appendDomId); 1503 dimIdList.push_back(dimYid); 1504 } 1505 dimCoordList.push_back(StdString("nav_lon").append(appendDomId)); 1506 dimCoordList.push_back(StdString("nav_lat").append(appendDomId)); 1507 break ; 1508 case CDomain::type_attr::rectilinear: 1509 if (!compressedOutput || !domain->isCompressible()) 1510 { 1511 dimXid = StdString("lon").append(appendDomId); 1512 dimIdList.push_back(dimXid); 1513 dimYid = StdString("lat").append(appendDomId); 1514 dimIdList.push_back(dimYid); 1515 } 1516 break ; 1517 case CDomain::type_attr::unstructured: 1518 { 1519 if (SuperClassWriter::useCFConvention) 1520 { 1521 dimXid = StdString("cell").append(appendDomId); 1522 dimIdList.push_back(dimXid); 1523 dimCoordList.push_back(StdString("lon").append(appendDomId)); 1524 dimCoordList.push_back(StdString("lat").append(appendDomId)); 1525 } 1526 else 1527 { 1528 StdString domainName = domain->name; 1529 if (domain->nvertex == 1) 1490 1530 { 1491 dimIdList.push_back(domId + "_points"); 1492 field->setUseCompressedOutput(); 1531 dimXid = "n" + domainName + "_node"; 1532 dimIdList.push_back(dimXid); 1533 dimCoordList.push_back(StdString(domainName + "_node_x")); 1534 dimCoordList.push_back(StdString(domainName + "_node_y")); 1493 1535 } 1494 1495 switch (domain->type) 1536 else if (domain->nvertex == 2) 1496 1537 { 1497 case CDomain::type_attr::curvilinear: 1498 if (!compressedOutput || !domain->isCompressible()) 1499 { 1500 dimXid = StdString("x").append(appendDomId); 1501 dimIdList.push_back(dimXid); 1502 dimYid = StdString("y").append(appendDomId); 1503 dimIdList.push_back(dimYid); 1504 } 1505 dimCoordList.push_back(StdString("nav_lon").append(appendDomId)); 1506 dimCoordList.push_back(StdString("nav_lat").append(appendDomId)); 1507 break ; 1508 case CDomain::type_attr::rectilinear: 1509 if (!compressedOutput || !domain->isCompressible()) 1510 { 1511 dimXid = StdString("lon").append(appendDomId); 1512 dimIdList.push_back(dimXid); 1513 dimYid = StdString("lat").append(appendDomId); 1514 dimIdList.push_back(dimYid); 1515 } 1516 break ; 1517 case CDomain::type_attr::unstructured: 1518 { 1519 if (SuperClassWriter::useCFConvention) 1520 { 1521 dimXid = StdString("cell").append(appendDomId); 1522 dimIdList.push_back(dimXid); 1523 dimCoordList.push_back(StdString("lon").append(appendDomId)); 1524 dimCoordList.push_back(StdString("lat").append(appendDomId)); 1525 } 1526 else 1527 { 1528 StdString domainName = domain->name; 1529 if (domain->nvertex == 1) 1530 { 1531 dimXid = "n" + domainName + "_node"; 1532 dimIdList.push_back(dimXid); 1533 dimCoordList.push_back(StdString(domainName + "_node_x")); 1534 dimCoordList.push_back(StdString(domainName + "_node_y")); 1535 } 1536 else if (domain->nvertex == 2) 1537 { 1538 dimXid = "n" + domainName + "_edge"; 1539 dimIdList.push_back(dimXid); 1540 dimCoordList.push_back(StdString(domainName + "_edge_x")); 1541 dimCoordList.push_back(StdString(domainName + "_edge_y")); 1542 } 1543 else 1544 { 1545 dimXid = "n" + domainName + "_face"; 1546 dimIdList.push_back(dimXid); 1547 dimCoordList.push_back(StdString(domainName + "_face_x")); 1548 dimCoordList.push_back(StdString(domainName + "_face_y")); 1549 } 1550 } // ugrid convention 1551 } // case unstructured domain 1552 } 1553 1554 if (domain->hasArea) 1555 { 1556 hasArea = true; 1557 cellMeasures += " area" + appendDomId; 1558 } 1559 ++idxDomain; 1560 } 1561 else if (1 == axisDomainOrder(i)) 1562 { 1563 CAxis* axis = CAxis::get(axisList[idxAxis]); 1564 StdString axisId = axis->getAxisOutputName(); 1565 1566 if (compressedOutput && axis->isCompressible()) 1567 { 1568 dimIdList.push_back(axisId + "_points"); 1569 field->setUseCompressedOutput(); 1538 dimXid = "n" + domainName + "_edge"; 1539 dimIdList.push_back(dimXid); 1540 dimCoordList.push_back(StdString(domainName + "_edge_x")); 1541 dimCoordList.push_back(StdString(domainName + "_edge_y")); 1570 1542 } 1571 1543 else 1572 dimIdList.push_back(axisId); 1573 1574 dimCoordList.push_back(axisId); 1575 ++idxAxis; 1576 } 1577 else // scalar 1578 { 1544 { 1545 dimXid = "n" + domainName + "_face"; 1546 dimIdList.push_back(dimXid); 1547 dimCoordList.push_back(StdString(domainName + "_face_x")); 1548 dimCoordList.push_back(StdString(domainName + "_face_y")); 1549 } 1550 } // ugrid convention 1551 } // case unstructured domain 1552 } 1553 1554 if (domain->hasArea) 1555 { 1556 hasArea = true; 1557 cellMeasures += " area" + appendDomId; 1558 } 1559 ++idxDomain; 1560 } 1561 else if (1 == axisDomainOrder(i)) 1562 { 1563 CAxis* axis = CAxis::get(axisList[idxAxis]); 1564 StdString axisId = axis->getAxisOutputName(); 1565 1566 if (compressedOutput && axis->isCompressible()) 1567 { 1568 dimIdList.push_back(axisId + "_points"); 1569 field->setUseCompressedOutput(); 1570 } 1571 else 1572 dimIdList.push_back(axisId); 1573 1574 dimCoordList.push_back(axisId); 1575 ++idxAxis; 1576 } 1577 else // scalar 1578 { 1579 1579 /* Do nothing here */ 1580 }1581 }1580 } 1581 } 1582 1582 1583 1583 /* … … 1589 1589 : latid; 1590 1590 */ 1591 StdString fieldid = field->getFieldOutputName();1592 1593 nc_type type ;1594 if (field->prec.isEmpty()) type = NC_FLOAT ;1595 else1596 {1597 if (field->prec==2) type = NC_SHORT ;1598 else if (field->prec==4) type = NC_FLOAT ;1599 else if (field->prec==8) type = NC_DOUBLE ;1600 }1601 1602 bool wtime = !(!field->operation.isEmpty() && field->getOperationTimeType() == func::CFunctor::once);1603 1604 if (wtime)1605 {1606 1607 //StdOStringStream oss;1608 // oss << "time_" << field->operation.getValue()1609 // << "_" << field->getRelFile()->output_freq.getValue();1591 StdString fieldid = field->getFieldOutputName(); 1592 1593 nc_type type ; 1594 if (field->prec.isEmpty()) type = NC_FLOAT ; 1595 else 1596 { 1597 if (field->prec==2) type = NC_SHORT ; 1598 else if (field->prec==4) type = NC_FLOAT ; 1599 else if (field->prec==8) type = NC_DOUBLE ; 1600 } 1601 1602 bool wtime = !(!field->operation.isEmpty() && field->getOperationTimeType() == func::CFunctor::once); 1603 1604 if (wtime) 1605 { 1606 1607 //StdOStringStream oss; 1608 // oss << "time_" << field->operation.getValue() 1609 // << "_" << field->getRelFile()->output_freq.getValue(); 1610 1610 //oss 1611 if (field->getOperationTimeType() == func::CFunctor::instant) coodinates.push_back(string("time_instant"));1612 else if (field->getOperationTimeType() == func::CFunctor::centered) coodinates.push_back(string("time_centered"));1613 dims.push_back(timeid);1614 }1615 1616 if (compressedOutput && grid->isCompressible())1617 {1618 dims.push_back(grid->getId() + "_points");1619 field->setUseCompressedOutput();1620 }1621 else1622 {1623 while (!dimIdList.empty())1624 {1625 dims.push_back(dimIdList.back());1626 dimIdList.pop_back();1627 }1628 }1629 1630 while (!dimCoordList.empty())1631 {1632 coodinates.push_back(dimCoordList.back());1633 dimCoordList.pop_back();1634 }1635 1636 try1637 {1611 if (field->getOperationTimeType() == func::CFunctor::instant) coodinates.push_back(string("time_instant")); 1612 else if (field->getOperationTimeType() == func::CFunctor::centered) coodinates.push_back(string("time_centered")); 1613 dims.push_back(timeid); 1614 } 1615 1616 if (compressedOutput && grid->isCompressible()) 1617 { 1618 dims.push_back(grid->getId() + "_points"); 1619 field->setUseCompressedOutput(); 1620 } 1621 else 1622 { 1623 while (!dimIdList.empty()) 1624 { 1625 dims.push_back(dimIdList.back()); 1626 dimIdList.pop_back(); 1627 } 1628 } 1629 1630 while (!dimCoordList.empty()) 1631 { 1632 coodinates.push_back(dimCoordList.back()); 1633 dimCoordList.pop_back(); 1634 } 1635 1636 try 1637 { 1638 1638 SuperClassWriter::addVariable(fieldid, type, dims); 1639 1639 … … 1650 1650 ("units", field->unit.getValue(), &fieldid); 1651 1651 1652 // Ugrid field attributes "mesh" and "location" 1653 if (!SuperClassWriter::useCFConvention) 1654 { 1655 if (!domainList.empty()) 1656 { 1657 CDomain* domain = CDomain::get(domainList[0]); // Suppose that we have only domain 1658 StdString mesh = domain->name; 1659 SuperClassWriter::addAttribute("mesh", mesh, &fieldid); 1660 StdString location; 1661 if (domain->nvertex == 1) 1662 location = "node"; 1663 else if (domain->nvertex == 2) 1664 location = "edge"; 1665 else if (domain->nvertex > 2) 1666 location = "face"; 1667 SuperClassWriter::addAttribute("location", location, &fieldid); 1668 } 1669 1670 } 1671 1672 if (!field->valid_min.isEmpty()) 1652 if (!field->valid_min.isEmpty()) 1673 1653 SuperClassWriter::addAttribute 1674 1654 ("valid_min", field->valid_min.getValue(), &fieldid); … … 1694 1674 vector<CVariable*> listVars = field->getAllVariables() ; 1695 1675 for (vector<CVariable*>::iterator it = listVars.begin() ;it != listVars.end(); it++) writeAttribute_(*it, fieldid) ; 1696 1697 bool alreadyAddCellMethod = false;1698 StdString cellMethodsPrefix(""), cellMethodsSuffix("");1699 if (!field->cell_methods.isEmpty())1700 {1701 StdString cellMethodString = field->cell_methods;1702 if (field->cell_methods_mode.isEmpty() ||1703 (CField::cell_methods_mode_attr::overwrite == field->cell_methods_mode))1704 {1705 SuperClassWriter::addAttribute("cell_methods", cellMethodString, &fieldid);1706 alreadyAddCellMethod = true;1707 }1708 else1709 {1710 switch (field->cell_methods_mode)1711 {1712 case (CField::cell_methods_mode_attr::prefix):1713 cellMethodsPrefix = cellMethodString;1714 cellMethodsPrefix += " ";1715 break;1716 case (CField::cell_methods_mode_attr::suffix):1717 cellMethodsSuffix = " ";1718 cellMethodsSuffix += cellMethodString;1719 break;1720 case (CField::cell_methods_mode_attr::none):1721 break;1722 default:1723 break;1724 }1725 }1726 }1727 1676 1728 1677 … … 1738 1687 SuperClassWriter::addAttribute("interval_write", freqOut.toStringUDUnits(), &fieldid); 1739 1688 1740 StdString cellMethods (cellMethodsPrefix + "time: ");1689 StdString cellMethods = "time: "; 1741 1690 if (field->operation.getValue() == "instant") cellMethods += "point"; 1742 1691 else if (field->operation.getValue() == "average") cellMethods += "mean"; … … 1745 1694 if (freqOp.resolve(*context->calendar) != freqOut.resolve(*context->calendar)) 1746 1695 cellMethods += " (interval: " + freqOpStr + ")"; 1747 cellMethods += cellMethodsSuffix; 1748 if (!alreadyAddCellMethod) 1749 SuperClassWriter::addAttribute("cell_methods", cellMethods, &fieldid); 1696 SuperClassWriter::addAttribute("cell_methods", cellMethods, &fieldid); 1750 1697 } 1751 1698 … … 1813 1760 if (SuperClassWriter::useCFConvention) 1814 1761 this->writeFileAttributes(filename, description, 1815 StdString("CF-1. 6"),1762 StdString("CF-1.5"), 1816 1763 StdString("An IPSL model"), 1817 1764 this->getTimeStamp()); … … 1981 1928 if (!field->wasWritten()) 1982 1929 { 1983 if (appendMode && field->file->record_offset.isEmpty() && 1984 field->getOperationTimeType() != func::CFunctor::once) 1930 if (appendMode && field->file->record_offset.isEmpty()) 1985 1931 { 1986 1932 field->resetNStep(getRecordFromTime(field->last_Write_srv) + 1); … … 2015 1961 time_data_bound(1) = lastWrite; 2016 1962 } 2017 2018 if (field->file->time_counter.isEmpty()) 2019 if (field->hasTimeInstant && !field->hasTimeCentered) 2020 time_counter(0) = lastWrite; 2021 else 2022 time_counter(0) = (lastWrite + lastLastWrite) / 2; 2023 2024 else if (field->file->time_counter == CFile::time_counter_attr::instant) 1963 1964 if (field->file->time_counter == CFile::time_counter_attr::instant) 2025 1965 time_counter(0) = lastWrite; 2026 1966 else if (field->file->time_counter == CFile::time_counter_attr::centered) … … 2030 1970 2031 1971 2032 if (field->file->time_counter.isEmpty()) 2033 if (field->hasTimeInstant && !field->hasTimeCentered) 2034 time_counter_bound(0) = time_counter_bound(1) = lastWrite; 2035 else 2036 { 2037 time_counter_bound(0) = lastLastWrite; 2038 time_counter_bound(1) = lastWrite; 2039 } 2040 else if (field->file->time_counter == CFile::time_counter_attr::instant) 1972 if (field->file->time_counter == CFile::time_counter_attr::instant) 2041 1973 time_counter_bound(0) = time_counter_bound(1) = lastWrite; 2042 1974 else if (field->file->time_counter == CFile::time_counter_attr::centered) … … 2087 2019 SuperClassWriter::writeData(time_data, timeAxisId, isCollective, field->getNStep() - 1); 2088 2020 SuperClassWriter::writeData(time_data_bound, timeAxisBoundId, isCollective, field->getNStep() - 1); 2089 if (field->file->time_counter.isEmpty() || 2090 (field->file->time_counter != CFile::time_counter_attr::none)) 2021 if (field->file->time_counter != CFile::time_counter_attr::none) 2091 2022 { 2092 2023 SuperClassWriter::writeData(time_counter, getTimeCounterName(), isCollective, field->getNStep() - 1); 2093 if (field->file->time_counter.isEmpty() || 2094 (field->file->time_counter != CFile::time_counter_attr::record)) 2024 if (field->file->time_counter != CFile::time_counter_attr::record) 2095 2025 SuperClassWriter::writeData(time_counter_bound, timeBoundId, isCollective, field->getNStep() - 1); 2096 2026 } … … 2225 2155 SuperClassWriter::writeTimeAxisData(time_data, timeAxisId, isCollective, field->getNStep() - 1, isRoot); 2226 2156 SuperClassWriter::writeTimeAxisData(time_data_bound, timeAxisBoundId, isCollective, field->getNStep() - 1, isRoot); 2227 if (field->file->time_counter.isEmpty() || 2228 (field->file->time_counter != CFile::time_counter_attr::none)) 2157 if (field->file->time_counter != CFile::time_counter_attr::none) 2229 2158 { 2230 2159 SuperClassWriter::writeTimeAxisData(time_counter, getTimeCounterName(), isCollective, field->getNStep() - 1, isRoot); 2231 if (field->file->time_counter.isEmpty() || 2232 (field->file->time_counter != CFile::time_counter_attr::record)) 2160 if (field->file->time_counter != CFile::time_counter_attr::record) 2233 2161 SuperClassWriter::writeTimeAxisData(time_counter_bound, timeBoundId, isCollective, field->getNStep() - 1, isRoot); 2234 2162 } … … 2271 2199 StdString timeid(getTimeCounterName()); 2272 2200 StdString timeBoundId("axis_nbounds"); 2273 2201 2274 2202 if (field->getOperationTimeType() == func::CFunctor::instant) 2275 2203 { 2276 2204 axisid = "time_instant"; 2277 2205 axisBoundId = "time_instant_bounds"; 2278 field->hasTimeInstant = true; 2279 } 2280 2281 if (field->getOperationTimeType() == func::CFunctor::centered) 2282 { 2283 field->hasTimeCentered = true; 2284 } 2206 } 2285 2207 2286 2208 try … … 2314 2236 } 2315 2237 2316 if (field->file->time_counter.isEmpty() || 2317 (field->file->time_counter != CFile::time_counter_attr::none)) 2238 if (field->file->time_counter != CFile::time_counter_attr::none) 2318 2239 { 2319 2240 // Adding time_counter … … 2327 2248 SuperClassWriter::addAttribute("axis", string("T"), &axisid); 2328 2249 2329 if (field->file->time_counter.isEmpty() || 2330 (field->file->time_counter != CFile::time_counter_attr::record)) 2250 if (field->file->time_counter != CFile::time_counter_attr::record) 2331 2251 { 2332 2252 CDate timeOrigin = cal->getTimeOrigin(); … … 2340 2260 2341 2261 // Adding time_counter_bound dimension 2342 if (field->file->time_counter.isEmpty() || 2343 (field->file->time_counter != CFile::time_counter_attr::record)) 2262 if (field->file->time_counter != CFile::time_counter_attr::record) 2344 2263 { 2345 2264 if (!SuperClassWriter::varExist(axisBoundId)) … … 2516 2435 SuperClassWriter::addAttribute("title" , description); 2517 2436 SuperClassWriter::addAttribute("Conventions", conventions); 2518 //SuperClassWriter::addAttribute("production" , production);2437 SuperClassWriter::addAttribute("production" , production); 2519 2438 SuperClassWriter::addAttribute("timeStamp" , timeStamp); 2520 2439 }
Note: See TracChangeset
for help on using the changeset viewer.