#include "nc4_data_output.hpp" #include #include "attribute_template.hpp" #include "group_template.hpp" #include "file.hpp" #include "calendar.hpp" #include "context.hpp" #include "context_server.hpp" #include "netCdfException.hpp" #include "exception.hpp" namespace xios { /// ////////////////////// Définitions ////////////////////// /// CNc4DataOutput::CNc4DataOutput (const StdString & filename, bool exist) : SuperClass() , SuperClassWriter(filename, exist) , filename(filename) { StdString timeid = StdString("time_counter"); SuperClass::type = MULTI_FILE; // if (!exist) // SuperClassWriter::addDimension(timeid); } CNc4DataOutput::CNc4DataOutput (const StdString & filename, bool exist, bool useClassicFormat, MPI_Comm comm_file,bool multifile, bool isCollective) : SuperClass() , SuperClassWriter(filename, exist, useClassicFormat, &comm_file, multifile) , comm_file(comm_file) , filename(filename) , isCollective(isCollective) { StdString timeid = StdString("time_counter"); SuperClass::type = (multifile) ? MULTI_FILE : ONE_FILE; // if (!exist) // SuperClassWriter::addDimension(timeid); } CNc4DataOutput::~CNc4DataOutput(void) { /* Ne rien faire de plus */ } ///-------------------------------------------------------------- const StdString & CNc4DataOutput::getFileName(void) const { return (this->filename); } //--------------------------------------------------------------- void CNc4DataOutput::writeDomain_(CDomain* domain) { if (domain->type == CDomain::type_attr::unstructured) { writeUnstructuredDomain(domain) ; return ; } CContext* context = CContext::getCurrent() ; CContextServer* server=context->server ; if (domain->IsWritten(this->filename)) return; domain->checkAttributes(); if (domain->isEmpty()) if (SuperClass::type==MULTI_FILE) return ; std::vector dim0, dim1; StdString domid = (!domain->name.isEmpty()) ? domain->name.getValue() : domain->getId(); StdString appendDomid = (singleDomain) ? "" : "_"+domid ; StdString dimXid, dimYid ; switch (domain->type) { case CDomain::type_attr::curvilinear : dimXid = StdString("x").append(appendDomid); dimYid = StdString("y").append(appendDomid); break ; case CDomain::type_attr::regular : dimXid = StdString("lon").append(appendDomid); dimYid = StdString("lat").append(appendDomid); break; case CDomain::type_attr::unstructured : dimXid = StdString("cell").append(appendDomid); break; } string lonid,latid,bounds_lonid,bounds_latid ; string areaId = "area" + appendDomid; /* StdString lonid_loc = (server->intraCommSize > 1) ? StdString("lon").append(appendDomid).append("_local") : lonid; StdString latid_loc = (server->intraCommSize > 1) ? StdString("lat").append(appendDomid).append("_local") : latid; */ try { switch (SuperClass::type) { case (MULTI_FILE) : { // if (domain->isEmpty()) return; if (server->intraCommSize > 1) { // SuperClassWriter::addDimension(lonid, domain->zoom_ni.getValue()); // SuperClassWriter::addDimension(latid, domain->zoom_nj.getValue()); } switch (domain->type) { case CDomain::type_attr::curvilinear : dim0.push_back(dimYid); dim0.push_back(dimXid); lonid = StdString("nav_lon").append(appendDomid); latid = StdString("nav_lat").append(appendDomid); break ; case CDomain::type_attr::regular : lonid = StdString("lon").append(appendDomid); latid = StdString("lat").append(appendDomid); dim0.push_back(dimYid); dim1.push_back(dimXid); break; case CDomain::type_attr::unstructured : lonid = StdString("lon").append(appendDomid); latid = StdString("lat").append(appendDomid); bounds_lonid=string("bounds_lon").append(appendDomid); bounds_latid=string("bounds_lat").append(appendDomid); dim0.push_back(dimXid); break; } if (domain->type == CDomain::type_attr::unstructured) { SuperClassWriter::addDimension(dimXid, domain->nj_glo); } else { SuperClassWriter::addDimension(dimXid, domain->zoom_ni_srv); SuperClassWriter::addDimension(dimYid, domain->zoom_nj_srv); } if (server->intraCommSize > 1) { if (domain->type != CDomain::type_attr::unstructured) { this->writeLocalAttributes(domain->zoom_ibegin_srv, domain->zoom_ni_srv, domain->zoom_jbegin_srv, domain->zoom_nj_srv, appendDomid); if (singleDomain) this->writeLocalAttributes_IOIPSL(domain->zoom_ibegin_srv, domain->zoom_ni_srv, domain->zoom_jbegin_srv, domain->zoom_nj_srv, domain->ni_glo,domain->nj_glo, server->intraCommRank,server->intraCommSize); } } switch (domain->type) { case CDomain::type_attr::curvilinear : SuperClassWriter::addVariable(latid, NC_FLOAT, dim0); SuperClassWriter::addVariable(lonid, NC_FLOAT, dim0); break ; case CDomain::type_attr::regular : SuperClassWriter::addVariable(latid, NC_FLOAT, dim0); SuperClassWriter::addVariable(lonid, NC_FLOAT, dim1); break ; case CDomain::type_attr::unstructured : SuperClassWriter::addVariable(latid, NC_FLOAT, dim0); SuperClassWriter::addVariable(lonid, NC_FLOAT, dim0); } this->writeAxisAttributes(lonid, "X", "longitude", "Longitude", "degrees_east", domid); this->writeAxisAttributes(latid, "Y", "latitude", "Latitude", "degrees_north", domid); dim0.clear(); if (domain->type != CDomain::type_attr::unstructured) dim0.push_back(dimYid); dim0.push_back(dimXid); // supress mask if (server->intraCommSize > 1) // supress mask { // supress mask SuperClassWriter::addVariable(maskid, NC_INT, dim0); // supress mask // supress mask this->writeMaskAttributes(maskid, // supress mask domain->data_dim.getValue()/*, // supress mask domain->data_ni.getValue(), // supress mask domain->data_nj.getValue(), // supress mask domain->data_ibegin.getValue(), // supress mask domain->data_jbegin.getValue()*/); // supress mask } //SuperClassWriter::setDefaultValue(maskid, &dvm); if (domain->hasArea) { SuperClassWriter::addVariable(areaId, NC_FLOAT, dim0); SuperClassWriter::addAttribute("units", StdString("m2"), &areaId); } SuperClassWriter::definition_end(); switch (domain->type) { case CDomain::type_attr::curvilinear : SuperClassWriter::writeData(domain->latvalue_srv, latid, isCollective, 0); SuperClassWriter::writeData(domain->lonvalue_srv, lonid, isCollective, 0); break; case CDomain::type_attr::regular : CArray lat = domain->latvalue_srv(Range(fromStart,toEnd,domain->zoom_ni_srv)) ; SuperClassWriter::writeData(CArray(lat.copy()), latid, isCollective, 0); CArray lon=domain->lonvalue_srv(Range(0,domain->zoom_ni_srv-1)) ; SuperClassWriter::writeData(CArray(lon.copy()), lonid, isCollective, 0); break; } if (domain->hasArea) SuperClassWriter::writeData(domain->area_srv, areaId, isCollective, 0); SuperClassWriter::definition_start(); break; } case (ONE_FILE) : { SuperClassWriter::addDimension(dimXid, domain->zoom_ni.getValue()); SuperClassWriter::addDimension(dimYid, domain->zoom_nj.getValue()); switch (domain->type) { case CDomain::type_attr::curvilinear : dim0.push_back(dimYid); dim0.push_back(dimXid); lonid = StdString("nav_lon").append(appendDomid); latid = StdString("nav_lat").append(appendDomid); SuperClassWriter::addVariable(latid, NC_FLOAT, dim0); SuperClassWriter::addVariable(lonid, NC_FLOAT, dim0); break; case CDomain::type_attr::regular : dim0.push_back(dimYid); dim1.push_back(dimXid); lonid = StdString("lon").append(appendDomid); latid = StdString("lat").append(appendDomid); SuperClassWriter::addVariable(latid, NC_FLOAT, dim0); SuperClassWriter::addVariable(lonid, NC_FLOAT, dim1); break; } if (domain->hasArea) { dim0.clear(); dim0.push_back(dimYid); dim0.push_back(dimXid); SuperClassWriter::addVariable(areaId, NC_FLOAT, dim0); SuperClassWriter::addAttribute("units", StdString("m2"), &areaId); dim0.clear(); } this->writeAxisAttributes (lonid, "X", "longitude", "Longitude", "degrees_east", domid); this->writeAxisAttributes (latid, "Y", "latitude", "Latitude", "degrees_north", domid); SuperClassWriter::definition_end(); switch (domain->type) { case CDomain::type_attr::curvilinear : { std::vector start(2) ; std::vector count(2) ; if (domain->isEmpty()) { start[0]=0 ; start[1]=0 ; count[0]=0 ; count[1]=0 ; } else { start[1]=domain->zoom_ibegin_srv-domain->zoom_ibegin.getValue() ; start [0]=domain->zoom_jbegin_srv-domain->zoom_jbegin.getValue() ; count[1]=domain->zoom_ni_srv ; count[0]=domain->zoom_nj_srv ; } SuperClassWriter::writeData(domain->latvalue_srv, latid, isCollective, 0,&start,&count); SuperClassWriter::writeData(domain->lonvalue_srv, lonid, isCollective, 0,&start,&count); break; } case CDomain::type_attr::regular : { std::vector start(1) ; std::vector count(1) ; if (domain->isEmpty()) { start[0]=0 ; count[0]=0 ; SuperClassWriter::writeData(domain->latvalue_srv, latid, isCollective, 0,&start,&count); SuperClassWriter::writeData(domain->lonvalue_srv, lonid, isCollective, 0,&start,&count); } else { start[0]=domain->zoom_jbegin_srv-domain->zoom_jbegin.getValue() ; count[0]=domain->zoom_nj_srv ; CArray lat = domain->latvalue_srv(Range(fromStart,toEnd,domain->zoom_ni_srv)) ; SuperClassWriter::writeData(CArray(lat.copy()), latid, isCollective, 0,&start,&count); start[0]=domain->zoom_ibegin_srv-domain->zoom_ibegin.getValue() ; count[0]=domain->zoom_ni_srv ; CArray lon=domain->lonvalue_srv(Range(0,domain->zoom_ni_srv-1)) ; SuperClassWriter::writeData(CArray(lon.copy()), lonid, isCollective, 0,&start,&count); } break; } } if (domain->hasArea) { std::vector start(2); std::vector count(2); if (domain->isEmpty()) { start[0] = 0; start[1] = 0; count[0] = 0; count[1] = 0; } else { start[1] = domain->zoom_ibegin_srv - domain->zoom_ibegin.getValue(); start[0] = domain->zoom_jbegin_srv - domain->zoom_jbegin.getValue(); count[1] = domain->zoom_ni_srv; count[0] = domain->zoom_nj_srv; } SuperClassWriter::writeData(domain->area_srv, areaId, isCollective, 0, &start, &count); } SuperClassWriter::definition_start(); break; } default : ERROR("CNc4DataOutput::writeDomain(domain)", << "[ type = " << SuperClass::type << "]" << " not implemented yet !"); } } catch (CNetCdfException& e) { StdString msg("On writing the domain : "); msg.append(domid); msg.append("\n"); msg.append("In the context : "); msg.append(context->getId()); msg.append("\n"); msg.append(e.what()); ERROR("CNc4DataOutput::writeDomain_(CDomain* domain)", << msg); } domain->addRelFile(this->filename); } void CNc4DataOutput::writeUnstructuredDomain(CDomain* domain) { CContext* context = CContext::getCurrent() ; CContextServer* server=context->server ; if (domain->IsWritten(this->filename)) return; domain->checkAttributes(); if (domain->isEmpty()) if (SuperClass::type==MULTI_FILE) return ; std::vector dim0, dim1; StdString domid = (!domain->name.isEmpty()) ? domain->name.getValue() : domain->getId(); StdString appendDomid = (singleDomain) ? "" : "_"+domid ; StdString dimXid = StdString("cell").append(appendDomid); StdString dimVertId = StdString("nvertex").append(appendDomid); string lonid,latid,bounds_lonid,bounds_latid ; string areaId = "area" + appendDomid; try { switch (SuperClass::type) { case (MULTI_FILE) : { lonid = StdString("lon").append(appendDomid); latid = StdString("lat").append(appendDomid); dim0.push_back(dimXid); SuperClassWriter::addDimension(dimXid, domain->zoom_nj_srv); SuperClassWriter::addVariable(latid, NC_FLOAT, dim0); SuperClassWriter::addVariable(lonid, NC_FLOAT, dim0); bounds_lonid = StdString("bounds_lon").append(appendDomid); bounds_latid = StdString("bounds_lat").append(appendDomid); this->writeAxisAttributes(lonid, "X", "longitude", "Longitude", "degrees_east", domid); if (domain->hasBounds) SuperClassWriter::addAttribute("bounds",bounds_lonid, &lonid); this->writeAxisAttributes(latid, "Y", "latitude", "Latitude", "degrees_north", domid); if (domain->hasBounds) SuperClassWriter::addAttribute("bounds",bounds_latid, &latid); if (domain->hasBounds) SuperClassWriter::addDimension(dimVertId, domain->nvertex); dim0.clear(); if (domain->hasBounds) { dim0.push_back(dimXid); dim0.push_back(dimVertId); SuperClassWriter::addVariable(bounds_lonid, NC_FLOAT, dim0); SuperClassWriter::addVariable(bounds_latid, NC_FLOAT, dim0); } dim0.clear(); dim0.push_back(dimXid); if (domain->hasArea) { SuperClassWriter::addVariable(areaId, NC_FLOAT, dim0); SuperClassWriter::addAttribute("units", StdString("m2"), &areaId); } SuperClassWriter::definition_end(); SuperClassWriter::writeData(domain->latvalue_srv, latid, isCollective, 0); SuperClassWriter::writeData(domain->lonvalue_srv, lonid, isCollective, 0); if (domain->hasBounds) { SuperClassWriter::writeData(domain->bounds_lon_srv, bounds_lonid, isCollective, 0); SuperClassWriter::writeData(domain->bounds_lat_srv, bounds_latid, isCollective, 0); } if (domain->hasArea) SuperClassWriter::writeData(domain->area_srv, areaId, isCollective, 0); SuperClassWriter::definition_start(); break ; } case (ONE_FILE) : { lonid = StdString("lon").append(appendDomid); latid = StdString("lat").append(appendDomid); bounds_lonid = StdString("bounds_lon").append(appendDomid); bounds_latid = StdString("bounds_lat").append(appendDomid); dim0.push_back(dimXid); SuperClassWriter::addDimension(dimXid, domain->nj_glo); SuperClassWriter::addVariable(latid, NC_FLOAT, dim0); SuperClassWriter::addVariable(lonid, NC_FLOAT, dim0); this->writeAxisAttributes(lonid, "X", "longitude", "Longitude", "degrees_east", domid); if (domain->hasBounds) SuperClassWriter::addAttribute("bounds",bounds_lonid, &lonid); this->writeAxisAttributes(latid, "Y", "latitude", "Latitude", "degrees_north", domid); if (domain->hasBounds) SuperClassWriter::addAttribute("bounds",bounds_latid, &latid); if (domain->hasBounds) SuperClassWriter::addDimension(dimVertId, domain->nvertex); dim0.clear(); if (domain->hasBounds) { dim0.push_back(dimXid); dim0.push_back(dimVertId); SuperClassWriter::addVariable(bounds_lonid, NC_FLOAT, dim0); SuperClassWriter::addVariable(bounds_latid, NC_FLOAT, dim0); } if (domain->hasArea) { dim0.clear(); dim0.push_back(dimXid); SuperClassWriter::addVariable(areaId, NC_FLOAT, dim0); SuperClassWriter::addAttribute("units", StdString("m2"), &areaId); } SuperClassWriter::definition_end(); std::vector start(1), startBounds(2) ; std::vector count(1), countBounds(2) ; if (domain->isEmpty()) { start[0]=0 ; count[0]=0 ; startBounds[1]=0 ; countBounds[1]=domain->nvertex ; startBounds[0]=0 ; countBounds[0]=0 ; } else { start[0]=domain->zoom_jbegin_srv-domain->zoom_jbegin ; count[0]=domain->zoom_nj_srv ; startBounds[0]=domain->zoom_jbegin_srv-domain->zoom_jbegin ; startBounds[1]=0 ; countBounds[0]=domain->zoom_nj_srv ; countBounds[1]=domain->nvertex ; } SuperClassWriter::writeData(domain->latvalue_srv, latid, isCollective, 0,&start,&count); SuperClassWriter::writeData(domain->lonvalue_srv, lonid, isCollective, 0,&start,&count); if (domain->hasBounds) { SuperClassWriter::writeData(domain->bounds_lon_srv, bounds_lonid, isCollective, 0,&startBounds,&countBounds); SuperClassWriter::writeData(domain->bounds_lat_srv, bounds_latid, isCollective, 0,&startBounds,&countBounds); } if (domain->hasArea) SuperClassWriter::writeData(domain->area_srv, areaId, isCollective, 0, &start, &count); SuperClassWriter::definition_start(); break; } default : ERROR("CNc4DataOutput::writeDomain(domain)", << "[ type = " << SuperClass::type << "]" << " not implemented yet !"); } } catch (CNetCdfException& e) { StdString msg("On writing the domain : "); msg.append(domid); msg.append("\n"); msg.append("In the context : "); msg.append(context->getId()); msg.append("\n"); msg.append(e.what()); ERROR("CNc4DataOutput::writeUnstructuredDomain(CDomain* domain)", << msg); } domain->addRelFile(this->filename); } //-------------------------------------------------------------- void CNc4DataOutput::writeAxis_(CAxis* axis) { if (axis->IsWritten(this->filename)) return; axis->checkAttributes(); int zoom_size_srv = axis->zoom_size_srv; int zoom_begin_srv = axis->zoom_begin_srv; int zoom_size = (MULTI_FILE == SuperClass::type) ? zoom_size_srv : axis->zoom_size; int zoom_begin = (MULTI_FILE == SuperClass::type) ? zoom_begin_srv : axis->zoom_begin; std::vector dims; StdString axisid = !axis->name.isEmpty() ? axis->name.getValue() : axis->getId(); try { SuperClassWriter::addDimension(axisid, zoom_size); dims.push_back(axisid); switch (SuperClass::type) { case MULTI_FILE: case ONE_FILE: { SuperClassWriter::addVariable(axisid, NC_FLOAT, dims); SuperClassWriter::addAttribute("axis", StdString("Z"), &axisid); if (!axis->name.isEmpty()) SuperClassWriter::addAttribute("name", axis->name.getValue(), &axisid); if (!axis->standard_name.isEmpty()) SuperClassWriter::addAttribute("standard_name", axis->standard_name.getValue(), &axisid); if (!axis->long_name.isEmpty()) SuperClassWriter::addAttribute("long_name", axis->long_name.getValue(), &axisid); if (!axis->unit.isEmpty()) SuperClassWriter::addAttribute("units", axis->unit.getValue(), &axisid); if (!axis->positive.isEmpty()) if (axis->positive == CAxis::positive_attr::up) SuperClassWriter::addAttribute("positive", string("up"), &axisid); else SuperClassWriter::addAttribute("positive", string("down"), &axisid); StdString axisBoundsId = axisid + "_bounds"; if (!axis->bounds.isEmpty()) { dims.push_back("axis_nbounds"); SuperClassWriter::addVariable(axisBoundsId, NC_FLOAT, dims); SuperClassWriter::addAttribute("bounds", axisBoundsId, &axisid); } SuperClassWriter::definition_end(); CArray axis_value(zoom_size); for (int i = 0; i < zoom_size_srv; i++) axis_value(i) = axis->value(i + zoom_begin_srv); SuperClassWriter::writeData(axis_value, axisid, isCollective, 0); if (!axis->bounds.isEmpty()) { CArray axisBounds(zoom_size, 2); for (int i = 0; i < zoom_size_srv; i++) { axisBounds(i, 0) = axis->bounds(i + zoom_begin_srv, 0); axisBounds(i, 1) = axis->bounds(i + zoom_begin_srv, 1); } SuperClassWriter::writeData(axisBounds, axisBoundsId, isCollective, 0); } SuperClassWriter::definition_start(); break; } default : ERROR("CNc4DataOutput::writeDomain(domain)", << "[ type = " << SuperClass::type << "]" << " not implemented yet !"); } } catch (CNetCdfException& e) { StdString msg("On writing the axis : "); msg.append(axisid); msg.append("\n"); msg.append("In the context : "); CContext* context = CContext::getCurrent() ; msg.append(context->getId()); msg.append("\n"); msg.append(e.what()); ERROR("CNc4DataOutput::writeAxis_(CAxis* axis)", << msg); } axis->addRelFile(this->filename); } void CNc4DataOutput::writeTimeDimension_(void) { try { SuperClassWriter::addDimension("time_counter"); SuperClassWriter::addDimension("time_bounds", 2); } catch (CNetCdfException& e) { StdString msg("On writing time dimension : time_couter, time_bounds \n"); msg.append("In the context : "); CContext* context = CContext::getCurrent() ; msg.append(context->getId()); msg.append("\n"); msg.append(e.what()); ERROR("CNc4DataOutput::writeTimeDimension_(void)", << msg); } } //-------------------------------------------------------------- void CNc4DataOutput::writeField_(CField* field) { CContext* context = CContext::getCurrent() ; CContextServer* server=context->server ; std::vector dims, coodinates; CGrid* grid = field->grid; if (!grid->doGridHaveDataToWrite()) if (SuperClass::type==MULTI_FILE) return ; CArray axisDomainOrder = grid->axis_domain_order; int numElement = axisDomainOrder.numElements(), idxDomain = 0, idxAxis = 0; std::vector domainList = grid->getDomainList(); std::vector axisList = grid->getAxisList(); StdString timeid = StdString("time_counter"); StdString dimXid,dimYid; std::deque dimIdList, dimCoordList; bool hasArea = false; StdString cellMeasures = "area:"; for (int i = 0; i < numElement; ++i) { if (axisDomainOrder(i)) { CDomain* domain = CDomain::get(domainList[idxDomain]); StdString domid = (!domain->name.isEmpty()) ? domain->name.getValue() : domain->getId(); StdString appendDomid = (singleDomain) ? "" : "_"+domid ; switch (domain->type) { case CDomain::type_attr::curvilinear : dimXid = StdString("x").append(appendDomid); dimIdList.push_back(dimXid); dimYid = StdString("y").append(appendDomid); dimIdList.push_back(dimYid); dimCoordList.push_back(StdString("nav_lon").append(appendDomid)); dimCoordList.push_back(StdString("nav_lat").append(appendDomid)); break ; case CDomain::type_attr::regular : dimXid = StdString("lon").append(appendDomid); dimIdList.push_back(dimXid); dimYid = StdString("lat").append(appendDomid); dimIdList.push_back(dimYid); break ; case CDomain::type_attr::unstructured : dimXid = StdString("cell").append(appendDomid); dimIdList.push_back(dimXid); dimCoordList.push_back(StdString("lon").append(appendDomid)); dimCoordList.push_back(StdString("lat").append(appendDomid)); break ; } if (domain->hasArea) { hasArea = true; cellMeasures += " area" + appendDomid; } ++idxDomain; } else { CAxis* axis = CAxis::get(axisList[idxAxis]); StdString axisid = (!axis->name.isEmpty()) ? axis->name.getValue() : axis->getId(); dimIdList.push_back(axisid); dimCoordList.push_back(axisid); ++idxAxis; } } /* StdString lonid_loc = (server->intraCommSize > 1) ? StdString("lon").append(appendDomid).append("_local") : lonid; StdString latid_loc = (server->intraCommSize > 1) ? StdString("lat").append(appendDomid).append("_local") : latid; */ StdString fieldid = (!field->name.isEmpty()) ? field->name.getValue() : field->getBaseFieldReference()->getId(); // unsigned int ssize = domain->zoom_ni_loc.getValue() * domain->zoom_nj_loc.getValue(); // bool isCurvilinear = (domain->lonvalue.getValue()->size() == ssize); // bool isCurvilinear = domain->isCurvilinear ; nc_type type ; if (field->prec.isEmpty()) type = NC_FLOAT ; else { if (field->prec==2) type = NC_SHORT ; else if (field->prec==4) type = NC_FLOAT ; else if (field->prec==8) type = NC_DOUBLE ; } bool wtime = !(!field->operation.isEmpty() && field->foperation->timeType() == func::CFunctor::once); if (wtime) { //StdOStringStream oss; // oss << "time_" << field->operation.getValue() // << "_" << field->getRelFile()->output_freq.getValue(); //oss if (field->foperation->timeType() == func::CFunctor::instant) coodinates.push_back(string("time_instant")); else if (field->foperation->timeType() == func::CFunctor::centered) coodinates.push_back(string("time_centered")); dims.push_back(timeid); } while (!dimIdList.empty()) { dims.push_back(dimIdList.back()); dimIdList.pop_back(); } while (!dimCoordList.empty()) { coodinates.push_back(dimCoordList.back()); dimCoordList.pop_back(); } try { SuperClassWriter::addVariable(fieldid, type, dims); if (!field->standard_name.isEmpty()) SuperClassWriter::addAttribute ("standard_name", field->standard_name.getValue(), &fieldid); if (!field->long_name.isEmpty()) SuperClassWriter::addAttribute ("long_name", field->long_name.getValue(), &fieldid); if (!field->unit.isEmpty()) SuperClassWriter::addAttribute ("units", field->unit.getValue(), &fieldid); if (!field->valid_min.isEmpty()) SuperClassWriter::addAttribute ("valid_min", field->valid_min.getValue(), &fieldid); if (!field->valid_max.isEmpty()) SuperClassWriter::addAttribute ("valid_max", field->valid_max.getValue(), &fieldid); if (!field->scale_factor.isEmpty()) SuperClassWriter::addAttribute ("scale_factor", field->scale_factor.getValue(), &fieldid); if (!field->add_offset.isEmpty()) SuperClassWriter::addAttribute ("add_offset", field->add_offset.getValue(), &fieldid); SuperClassWriter::addAttribute ("online_operation", field->operation.getValue(), &fieldid); // write child variables as attributes vector listVars = field->getAllVariables() ; for (vector::iterator it = listVars.begin() ;it != listVars.end(); it++) writeAttribute_(*it, fieldid) ; if (wtime) { CDuration duration = field->freq_op.getValue(); duration.solveTimeStep(*(context->calendar)); SuperClassWriter::addAttribute("interval_operation", duration.toString(), &fieldid); duration = field->getRelFile()->output_freq.getValue(); duration.solveTimeStep(*(context->calendar)); SuperClassWriter::addAttribute("interval_write", duration.toString(), &fieldid); } if (hasArea) SuperClassWriter::addAttribute("cell_measures", cellMeasures, &fieldid); if (!field->default_value.isEmpty()) { double default_value = field->default_value.getValue(); float fdefault_value = (float)default_value; if (type == NC_DOUBLE) SuperClassWriter::setDefaultValue(fieldid, &default_value); else SuperClassWriter::setDefaultValue(fieldid, &fdefault_value); } else SuperClassWriter::setDefaultValue(fieldid, (double*)NULL); if (field->compression_level.isEmpty()) field->compression_level = field->file->compression_level.isEmpty() ? 0 : field->file->compression_level; SuperClassWriter::setCompressionLevel(fieldid, field->compression_level); { // Ecriture des coordonnées StdString coordstr; //boost::algorithm::join(coodinates, " ") std::vector::iterator itc = coodinates.begin(), endc = coodinates.end(); for (; itc!= endc; itc++) { StdString & coord = *itc; if (itc+1 != endc) coordstr.append(coord).append(" "); else coordstr.append(coord); } SuperClassWriter::addAttribute("coordinates", coordstr, &fieldid); } } catch (CNetCdfException& e) { StdString msg("On writing field : "); msg.append(fieldid); msg.append("\n"); msg.append("In the context : "); msg.append(context->getId()); msg.append("\n"); msg.append(e.what()); ERROR("CNc4DataOutput::writeField_(CField* field)", << msg); } } // void CNc4DataOutput::writeField_(CField* field) // { // CContext* context = CContext::getCurrent() ; // CContextServer* server=context->server ; // // std::vector dims, coodinates; // CGrid* grid = field->grid; // CDomain* domain = grid->domain; // // if (domain->isEmpty()) // if (SuperClass::type==MULTI_FILE) return ; // // StdString timeid = StdString("time_counter"); // StdString domid = (!domain->name.isEmpty()) // ? domain->name.getValue() : domain->getId(); // StdString appendDomid = (singleDomain) ? "" : "_"+domid ; // //// bool isCurvilinear = domain->isCurvilinear ; //// bool isCurvilinear = (domain->type == CDomain::type_attr::curvilinear) ; // // StdString dimXid,dimYid ; // // switch (domain->type) // { // case CDomain::type_attr::curvilinear : // dimXid = StdString("x").append(appendDomid); // dimYid = StdString("y").append(appendDomid); // break ; // case CDomain::type_attr::regular : // dimXid = StdString("lon").append(appendDomid); // dimYid = StdString("lat").append(appendDomid); // break ; // case CDomain::type_attr::unstructured : // dimXid = StdString("cell").append(appendDomid); // break ; // } // ///* // StdString lonid_loc = (server->intraCommSize > 1) // ? StdString("lon").append(appendDomid).append("_local") // : lonid; // StdString latid_loc = (server->intraCommSize > 1) // ? StdString("lat").append(appendDomid).append("_local") // : latid; //*/ // StdString fieldid = (!field->name.isEmpty()) // ? field->name.getValue() : field->getBaseFieldReference()->getId(); // //// unsigned int ssize = domain->zoom_ni_loc.getValue() * domain->zoom_nj_loc.getValue(); //// bool isCurvilinear = (domain->lonvalue.getValue()->size() == ssize); //// bool isCurvilinear = domain->isCurvilinear ; // // nc_type type ; // if (field->prec.isEmpty()) type = NC_FLOAT ; // else // { // if (field->prec==2) type = NC_SHORT ; // else if (field->prec==4) type = NC_FLOAT ; // else if (field->prec==8) type = NC_DOUBLE ; // } // // bool wtime = !(!field->operation.isEmpty() && field->foperation->timeType() == func::CFunctor::once); // // if (wtime) // { // // //StdOStringStream oss; // // oss << "time_" << field->operation.getValue() // // << "_" << field->getRelFile()->output_freq.getValue(); // //oss // if (field->foperation->timeType() == func::CFunctor::instant) coodinates.push_back(string("time_instant")); // else if (field->foperation->timeType() == func::CFunctor::centered) coodinates.push_back(string("time_centered")); // dims.push_back(timeid); // } // // std::vector axisList = grid->getAxisList(); // if (!axisList.empty()) // { // std::vector::const_iterator itAxis = axisList.begin(), iteAxis = axisList.end(); // for (; itAxis != iteAxis; ++itAxis) // { // CAxis* axis = CAxis::get(*itAxis); // StdString axisid = (!axis->name.isEmpty()) // ? axis->name.getValue() : axis->getId(); // // dims.push_back(axisid); // coodinates.push_back(axisid); // } // } // // switch (domain->type) // { // case CDomain::type_attr::curvilinear : // coodinates.push_back(StdString("nav_lon").append(appendDomid)); // coodinates.push_back(StdString("nav_lat").append(appendDomid)); // break; // case CDomain::type_attr::regular : // case CDomain::type_attr::unstructured : // coodinates.push_back(StdString("lon").append(appendDomid)); // coodinates.push_back(StdString("lat").append(appendDomid)); // break; // } // // if ( domain->type == CDomain::type_attr::curvilinear || domain->type == CDomain::type_attr::regular)dims.push_back(dimYid); // dims.push_back(dimXid); // // try // { // SuperClassWriter::addVariable(fieldid, type, dims); // // if (!field->standard_name.isEmpty()) // SuperClassWriter::addAttribute // ("standard_name", field->standard_name.getValue(), &fieldid); // // if (!field->long_name.isEmpty()) // SuperClassWriter::addAttribute // ("long_name", field->long_name.getValue(), &fieldid); // // if (!field->unit.isEmpty()) // SuperClassWriter::addAttribute // ("units", field->unit.getValue(), &fieldid); // // if (!field->valid_min.isEmpty()) // SuperClassWriter::addAttribute // ("valid_min", field->valid_min.getValue(), &fieldid); // // if (!field->valid_max.isEmpty()) // SuperClassWriter::addAttribute // ("valid_max", field->valid_max.getValue(), &fieldid); // // if (!field->scale_factor.isEmpty()) // SuperClassWriter::addAttribute // ("scale_factor", field->scale_factor.getValue(), &fieldid); // // if (!field->add_offset.isEmpty()) // SuperClassWriter::addAttribute // ("add_offset", field->add_offset.getValue(), &fieldid); // // SuperClassWriter::addAttribute // ("online_operation", field->operation.getValue(), &fieldid); // // // write child variables as attributes // // // vector listVars = field->getAllVariables() ; // for (vector::iterator it = listVars.begin() ;it != listVars.end(); it++) writeAttribute_(*it, fieldid) ; // // // if (wtime) // { // CDuration duration = field->freq_op.getValue(); // duration.solveTimeStep(*(context->calendar)); // SuperClassWriter::addAttribute("interval_operation", duration.toString(), &fieldid); // // duration = field->getRelFile()->output_freq.getValue(); // duration.solveTimeStep(*(context->calendar)); // SuperClassWriter::addAttribute("interval_write", duration.toString(), &fieldid); // } // // if (!field->default_value.isEmpty()) // { // double default_value = field->default_value.getValue(); // float fdefault_value = (float)default_value; // if (type == NC_DOUBLE) // SuperClassWriter::setDefaultValue(fieldid, &default_value); // else // SuperClassWriter::setDefaultValue(fieldid, &fdefault_value); // } // else // SuperClassWriter::setDefaultValue(fieldid, (double*)NULL); // // { // Ecriture des coordonnées // // StdString coordstr; //boost::algorithm::join(coodinates, " ") // std::vector::iterator // itc = coodinates.begin(), endc = coodinates.end(); // // for (; itc!= endc; itc++) // { // StdString & coord = *itc; // if (itc+1 != endc) // coordstr.append(coord).append(" "); // else coordstr.append(coord); // } // // SuperClassWriter::addAttribute("coordinates", coordstr, &fieldid); // // } // } // catch (CNetCdfException& e) // { // StdString msg("On writing field : "); // msg.append(fieldid); msg.append("\n"); // msg.append("In the context : "); // msg.append(context->getId()); msg.append("\n"); // msg.append(e.what()); // ERROR("CNc4DataOutput::writeField_(CField* field)", << msg); // } // } //-------------------------------------------------------------- void CNc4DataOutput::writeFile_ (CFile* file) { StdString filename = (!file->name.isEmpty()) ? file->name.getValue() : file->getId(); StdString description = (!file->description.isEmpty()) ? file->description.getValue() : StdString("Created by xios"); singleDomain = (file->nbDomains == 1); try { this->writeFileAttributes(filename, description, StdString("CF-1.1"), StdString("An IPSL model"), this->getTimeStamp()); if (file->nbAxis >= 1) SuperClassWriter::addDimension("axis_nbounds", 2); } catch (CNetCdfException& e) { StdString msg("On writing file : "); msg.append(filename); msg.append("\n"); msg.append("In the context : "); CContext* context = CContext::getCurrent() ; msg.append(context->getId()); msg.append("\n"); msg.append(e.what()); ERROR("CNc4DataOutput::writeFile_ (CFile* file)", << msg); } } void CNc4DataOutput::writeAttribute_ (CVariable* var, const string& fieldId) { string name ; if (!var->name.isEmpty()) name=var->name ; else if (var->hasId()) name=var->getId() ; else return ; try { if (var->type.getValue() == CVariable::type_attr::t_int || var->type.getValue() == CVariable::type_attr::t_int32) addAttribute(name, var->getData(), &fieldId); else if (var->type.getValue() == CVariable::type_attr::t_int16) addAttribute(name, var->getData(), &fieldId); else if (var->type.getValue() == CVariable::type_attr::t_float) addAttribute(name, var->getData(), &fieldId); else if (var->type.getValue() == CVariable::type_attr::t_double) addAttribute(name, var->getData(), &fieldId); else if (var->type.getValue() == CVariable::type_attr::t_string) addAttribute(name, var->getData(), &fieldId); else ERROR("CNc4DataOutput::writeAttribute_ (CVariable* var, const string& fieldId)", << "Unsupported variable of type " << var->type.getStringValue()); } catch (CNetCdfException& e) { StdString msg("On writing attributes of variable with name : "); msg.append(name); msg.append("in the field "); msg.append(fieldId); msg.append("\n"); msg.append("In the context : "); CContext* context = CContext::getCurrent() ; msg.append(context->getId()); msg.append("\n"); msg.append(e.what()); ERROR("CNc4DataOutput::writeAttribute_ (CVariable* var, const string& fieldId)", << msg); } } void CNc4DataOutput::writeAttribute_ (CVariable* var) { string name ; if (!var->name.isEmpty()) name=var->name ; else if (var->hasId()) name=var->getId() ; else return ; try { if (var->type.getValue() == CVariable::type_attr::t_int || var->type.getValue() == CVariable::type_attr::t_int32) addAttribute(name, var->getData()); else if (var->type.getValue() == CVariable::type_attr::t_int16) addAttribute(name, var->getData()); else if (var->type.getValue() == CVariable::type_attr::t_float) addAttribute(name, var->getData()); else if (var->type.getValue() == CVariable::type_attr::t_double) addAttribute(name, var->getData()); else if (var->type.getValue() == CVariable::type_attr::t_string) addAttribute(name, var->getData()); else ERROR("CNc4DataOutput::writeAttribute_ (CVariable* var)", << "Unsupported variable of type " << var->type.getStringValue()); } catch (CNetCdfException& e) { StdString msg("On writing attributes of variable with name : "); msg.append(name); msg.append("\n"); msg.append("In the context : "); CContext* context = CContext::getCurrent() ; msg.append(context->getId()); msg.append("\n"); msg.append(e.what()); ERROR("CNc4DataOutput::writeAttribute_ (CVariable* var)", << msg); } } void CNc4DataOutput::syncFile_ (void) { try { SuperClassWriter::sync() ; } catch (CNetCdfException& e) { StdString msg("On synchronizing the write among processes"); msg.append("In the context : "); CContext* context = CContext::getCurrent() ; msg.append(context->getId()); msg.append("\n"); msg.append(e.what()); ERROR("CNc4DataOutput::syncFile_ (void)", << msg); } } void CNc4DataOutput::closeFile_ (void) { try { SuperClassWriter::close() ; } catch (CNetCdfException& e) { StdString msg("On closing file"); msg.append("In the context : "); CContext* context = CContext::getCurrent() ; msg.append(context->getId()); msg.append("\n"); msg.append(e.what()); ERROR("CNc4DataOutput::syncFile_ (void)", << msg); } } //--------------------------------------------------------------- StdString CNc4DataOutput::getTimeStamp(void) const { const int buffer_size = 100; time_t rawtime; struct tm * timeinfo = NULL; char buffer [buffer_size]; time ( &rawtime ); timeinfo = localtime ( &rawtime ); strftime (buffer, buffer_size, "%Y-%b-%d %H:%M:%S %Z", timeinfo); return (StdString(buffer)); } //--------------------------------------------------------------- void CNc4DataOutput::writeFieldData_ (CField* field) { CContext* context = CContext::getCurrent() ; // if (field->getRelFile()->isSyncTime()) SuperClassWriter::sync() ; CContextServer* server=context->server ; CGrid* grid = field->grid ; if (!grid->doGridHaveDataToWrite()) if (SuperClass::type==MULTI_FILE || !isCollective) return ; StdString fieldid = (!field->name.isEmpty()) ? field->name.getValue() : field->getBaseFieldReference()->getId(); StdOStringStream oss; string timeAxisId ; if (field->foperation->timeType() == func::CFunctor::instant) timeAxisId="time_instant" ; else if (field->foperation->timeType() == func::CFunctor::centered) timeAxisId="time_centered" ; StdString timeBoundId("time_counter_bounds"); StdString timeAxisBoundId; if (field->foperation->timeType() == func::CFunctor::instant) timeAxisBoundId="time_instant_bounds" ; else if (field->foperation->timeType() == func::CFunctor::centered) timeAxisBoundId="time_centered_bounds" ; CArray time_data(1) ; CArray time_counter(1) ; CArray time_counter_bound(2); CArray time_data_bound(2); bool wtime = !(!field->operation.isEmpty() && (field->foperation->timeType() == func::CFunctor::once)); if (wtime) { time_counter(0)= (Time(*field->last_Write_srv) + Time(*field->lastlast_Write_srv)) / 2; if (field->foperation->timeType() == func::CFunctor::instant) time_data(0) = Time(*field->last_Write_srv); else if (field->foperation->timeType() == func::CFunctor::centered) time_data(0) = time_counter(0); time_counter_bound(0) = Time(*field->lastlast_Write_srv); time_counter_bound(1) = Time(*field->last_Write_srv); if (field->foperation->timeType() == func::CFunctor::instant) time_data_bound(0) = time_data_bound(1) = Time(*field->last_Write_srv); else if (field->foperation->timeType() == func::CFunctor::centered) { time_data_bound(0) = time_counter_bound(0); time_data_bound(1) = time_counter_bound(1); } } bool isRoot ; if (server->intraCommRank==0) isRoot=true ; else isRoot=false ; if (!field->scale_factor.isEmpty() || !field->add_offset.isEmpty()) { double scaleFactor=1. ; double addOffset=0. ; if (!field->scale_factor.isEmpty()) scaleFactor=field->scale_factor ; if (!field->add_offset.isEmpty()) addOffset=field->add_offset ; field->scaleFactorAddOffset(scaleFactor,addOffset) ; } try { CArray fieldData(grid->getWrittenDataSize()); if (!field->default_value.isEmpty()) fieldData = field->default_value; field->outputField(fieldData); if (!field->prec.isEmpty() && field->prec==2) fieldData=round(fieldData) ; switch (SuperClass::type) { case (MULTI_FILE) : { SuperClassWriter::writeData(fieldData, fieldid, isCollective, field->getNStep()-1); if (wtime) { SuperClassWriter::writeData(time_data, timeAxisId, isCollective, field->getNStep()-1); SuperClassWriter::writeData(time_counter, string("time_counter"), isCollective, field->getNStep()-1); SuperClassWriter::writeData(time_counter_bound, timeBoundId, isCollective, field->getNStep()-1); SuperClassWriter::writeData(time_data_bound, timeAxisBoundId, isCollective, field->getNStep()-1); } break ; } case (ONE_FILE) : { std::vector nZoomBeginGlobal = grid->getDistributionServer()->getZoomBeginGlobal(); std::vector nZoomBeginServer = grid->getDistributionServer()->getZoomBeginServer(); std::vector nZoomSizeServer = grid->getDistributionServer()->getZoomSizeServer(); int ssize = nZoomBeginGlobal.size(); std::vector start(ssize) ; std::vector count(ssize) ; for (int i = 0; i < ssize; ++i) { start[i] = nZoomBeginServer[ssize-i-1] - nZoomBeginGlobal[ssize-i-1]; count[i] = nZoomSizeServer[ssize-i-1]; } SuperClassWriter::writeData(fieldData, fieldid, isCollective, field->getNStep()-1,&start,&count ); if (wtime) { SuperClassWriter::writeTimeAxisData(time_data, timeAxisId, isCollective, field->getNStep()-1,isRoot ); SuperClassWriter::writeTimeAxisData(time_counter, string("time_counter"), isCollective, field->getNStep()-1,isRoot ); SuperClassWriter::writeTimeAxisData(time_counter_bound, timeBoundId, isCollective, field->getNStep()-1, isRoot ); SuperClassWriter::writeTimeAxisData(time_data_bound, timeAxisBoundId, isCollective, field->getNStep()-1, isRoot); } break; } } } catch (CNetCdfException& e) { StdString msg("On writing field data: "); msg.append(fieldid); msg.append("\n"); msg.append("In the context : "); msg.append(context->getId()); msg.append("\n"); msg.append(e.what()); ERROR("CNc4DataOutput::writeFieldData_ (CField* field)", << msg); } } // //--------------------------------------------------------------- // // void CNc4DataOutput::writeFieldData_ (CField* field) // { // CContext* context = CContext::getCurrent() ; //// if (field->getRelFile()->isSyncTime()) SuperClassWriter::sync() ; // CContextServer* server=context->server ; // // CGrid* grid = field->grid ; // CDomain* domain = grid->domain ; // // if(SuperClass::type==MULTI_FILE || !isCollective) if (domain->isEmpty()) return; // // // StdString fieldid = (!field->name.isEmpty()) // ? field->name.getValue() // : field->getBaseFieldReference()->getId(); // // StdOStringStream oss; // string timeAxisId ; // if (field->foperation->timeType() == func::CFunctor::instant) timeAxisId="time_instant" ; // else if (field->foperation->timeType() == func::CFunctor::centered) timeAxisId="time_centered" ; // // StdString timeBoundId("time_counter_bounds"); // // StdString timeAxisBoundId; // if (field->foperation->timeType() == func::CFunctor::instant) timeAxisBoundId="time_instant_bounds" ; // else if (field->foperation->timeType() == func::CFunctor::centered) timeAxisBoundId="time_centered_bounds" ; // // CArray time_data(1) ; // CArray time_counter(1) ; // CArray time_counter_bound(2); // CArray time_data_bound(2); // // bool wtime = !(!field->operation.isEmpty() && (field->foperation->timeType() == func::CFunctor::once)); // // if (wtime) // { // time_counter(0)= (Time(*field->last_Write_srv) + Time(*field->lastlast_Write_srv)) / 2; // if (field->foperation->timeType() == func::CFunctor::instant) // time_data(0) = Time(*field->last_Write_srv); // else if (field->foperation->timeType() == func::CFunctor::centered) time_data(0) = time_counter(0); // // time_counter_bound(0) = Time(*field->lastlast_Write_srv); // time_counter_bound(1) = Time(*field->last_Write_srv); // if (field->foperation->timeType() == func::CFunctor::instant) // time_data_bound(0) = time_data_bound(1) = Time(*field->last_Write_srv); // else if (field->foperation->timeType() == func::CFunctor::centered) // { // time_data_bound(0) = time_counter_bound(0); // time_data_bound(1) = time_counter_bound(1); // } // } // // bool isRoot ; // if (server->intraCommRank==0) isRoot=true ; // else isRoot=false ; // // if (!field->scale_factor.isEmpty() || !field->add_offset.isEmpty()) // { // double scaleFactor=1. ; // double addOffset=0. ; // if (!field->scale_factor.isEmpty()) scaleFactor=field->scale_factor ; // if (!field->add_offset.isEmpty()) addOffset=field->add_offset ; // field->scaleFactorAddOffset(scaleFactor,addOffset) ; // } // // try // { // if (grid->hasAxis()) // 3D // { // CAxis* axis = grid->axis ; // CArray field_data3D(domain->zoom_ni_srv,domain->zoom_nj_srv,axis->zoom_size) ; // if (!field->default_value.isEmpty()) field_data3D = field->default_value ; // // field->outputField(field_data3D); // // if (!field->prec.isEmpty() && field->prec==2) field_data3D=round(field_data3D) ; // // switch (SuperClass::type) // { // case (MULTI_FILE) : // { // SuperClassWriter::writeData(field_data3D, fieldid, isCollective, field->getNStep()-1); // if (wtime) // { // SuperClassWriter::writeData(time_data, timeAxisId, isCollective, field->getNStep()-1); // SuperClassWriter::writeData(time_counter, string("time_counter"), isCollective, field->getNStep()-1); // SuperClassWriter::writeData(time_counter_bound, timeBoundId, isCollective, field->getNStep()-1); // SuperClassWriter::writeData(time_data_bound, timeAxisBoundId, isCollective, field->getNStep()-1); // } // break ; // } // case (ONE_FILE) : // { // std::vector start(3) ; // std::vector count(3) ; // if (domain->isEmpty()) // { // start[0]=0 ; start[1]=0 ; start[2]=0 ; // count[0]=0 ; count[1]=0 ; start[2]=0 ; // } // else // { // // start[2]=domain->zoom_ibegin_loc.getValue()-domain->zoom_ibegin.getValue() ; start [1]=domain->zoom_jbegin_loc.getValue()-domain->zoom_jbegin.getValue() ; start[0]=0 ; // start[2]=domain->zoom_ibegin_srv-domain->zoom_ibegin.getValue() ; start [1]=domain->zoom_jbegin_srv-domain->zoom_jbegin.getValue() ; start[0]=0 ; // count[2]=domain->zoom_ni_srv ; count[1]=domain->zoom_nj_srv ; count[0] = axis->zoom_size.getValue(); // } // SuperClassWriter::writeData(field_data3D, fieldid, isCollective, field->getNStep()-1,&start,&count ); // if (wtime) // { // SuperClassWriter::writeTimeAxisData(time_data, timeAxisId, isCollective, field->getNStep()-1,isRoot ); // SuperClassWriter::writeTimeAxisData(time_counter, string("time_counter"), isCollective, field->getNStep()-1,isRoot ); // SuperClassWriter::writeTimeAxisData(time_counter_bound, timeBoundId, isCollective, field->getNStep()-1, isRoot ); // SuperClassWriter::writeTimeAxisData(time_data_bound, timeAxisBoundId, isCollective, field->getNStep()-1, isRoot); // } // break; // } // } // // } // else // 2D // { // CArray field_data2D(domain->zoom_ni_srv,domain->zoom_nj_srv) ; // if (!field->default_value.isEmpty()) field_data2D = field->default_value ; // field->outputField(field_data2D); // if (!field->prec.isEmpty() && field->prec==2) field_data2D=round(field_data2D) ; // switch (SuperClass::type) // { // case (MULTI_FILE) : // { // SuperClassWriter::writeData(field_data2D, fieldid, isCollective, field->getNStep()-1); // if (wtime) // { // SuperClassWriter::writeData(time_data, timeAxisId, isCollective, field->getNStep()-1); // SuperClassWriter::writeData(time_counter, string("time_counter"), isCollective, field->getNStep()-1); // SuperClassWriter::writeData(time_counter_bound, timeBoundId, isCollective, field->getNStep()-1); // SuperClassWriter::writeData(time_data_bound, timeAxisBoundId, isCollective, field->getNStep()-1); // } // break; // } // case (ONE_FILE) : // { // std::vector start(2) ; // std::vector count(2) ; // if (domain->isEmpty()) // { // start[0]=0 ; start[1]=0 ; // count[0]=0 ; count[1]=0 ; // } // else // { // start[1]=domain->zoom_ibegin_srv-domain->zoom_ibegin.getValue() ; start[0]=domain->zoom_jbegin_srv-domain->zoom_jbegin.getValue() ; // count[1]=domain->zoom_ni_srv ; count[0]=domain->zoom_nj_srv ; // } // // SuperClassWriter::writeData(field_data2D, fieldid, isCollective, field->getNStep()-1,&start,&count); // if (wtime) // { // SuperClassWriter::writeTimeAxisData(time_data, timeAxisId, isCollective, field->getNStep()-1,isRoot); // SuperClassWriter::writeTimeAxisData(time_counter, string("time_counter"), isCollective, field->getNStep()-1,isRoot); // SuperClassWriter::writeTimeAxisData(time_counter_bound, timeBoundId, isCollective, field->getNStep()-1, isRoot); // SuperClassWriter::writeTimeAxisData(time_data_bound, timeAxisBoundId, isCollective, field->getNStep()-1, isRoot); // } // break; // // } // } // } // } // catch (CNetCdfException& e) // { // StdString msg("On writing field data: "); // msg.append(fieldid); msg.append("\n"); // msg.append("In the context : "); // msg.append(context->getId()); msg.append("\n"); // msg.append(e.what()); // ERROR("CNc4DataOutput::writeFieldData_ (CField* field)", << msg); // } // } //--------------------------------------------------------------- void CNc4DataOutput::writeTimeAxis_ (CField* field, const boost::shared_ptr cal) { StdOStringStream oss; // if (field->operation.getValue().compare("once") == 0) return ; if (field->foperation->timeType() == func::CFunctor::once) return ; // oss << "time_" << field->operation.getValue() // << "_" << field->getRelFile()->output_freq.getValue(); // StdString axisid = oss.str(); // if (field->foperation->timeType() == func::CFunctor::centered) axisid="time_centered" ; // else if (field->foperation->timeType() == func::CFunctor::instant) axisid="time_instant" ; StdString axisid("time_centered") ; StdString axisBoundId("time_centered_bounds"); StdString timeid("time_counter"); StdString timeBoundId("time_bounds"); if (field->foperation->timeType() == func::CFunctor::instant) { axisid = "time_instant"; axisBoundId = "time_instant_bounds"; } try { // Adding time_instant or time_centered std::vector dims; dims.push_back(timeid); if (!SuperClassWriter::varExist(axisid)) { SuperClassWriter::addVariable(axisid, NC_DOUBLE, dims); CDate timeOrigin=cal->getTimeOrigin() ; StdOStringStream oss2; // oss2<writeTimeAxisAttributes (axisid, cal->getType(), StdString("seconds since ").append(strTimeOrigin), strTimeOrigin, axisBoundId); } // Adding time_instant_bounds or time_centered_bounds variables if (!SuperClassWriter::varExist(axisBoundId)) { dims.clear() ; dims.push_back(timeid); dims.push_back(timeBoundId); SuperClassWriter::addVariable(axisBoundId, NC_DOUBLE, dims); } // Adding time_counter axisid = "time_counter" ; axisBoundId = "time_counter_bounds" ; dims.clear() ; dims.push_back(timeid); if (!SuperClassWriter::varExist(axisid)) { SuperClassWriter::addVariable(axisid, NC_DOUBLE, dims); SuperClassWriter::addAttribute("axis", string("T"), &axisid); CDate timeOrigin=cal->getTimeOrigin() ; StdString strTimeOrigin=timeOrigin.toString() ; this->writeTimeAxisAttributes (axisid, cal->getType(), StdString("seconds since ").append(strTimeOrigin), strTimeOrigin, axisBoundId); } // Adding time_counter_bound dimension if (!SuperClassWriter::varExist(axisBoundId)) { dims.clear(); dims.push_back(timeid); dims.push_back(timeBoundId); SuperClassWriter::addVariable(axisBoundId, NC_DOUBLE, dims); } } catch (CNetCdfException& e) { StdString msg("On writing time axis data: "); msg.append("In the context : "); CContext* context = CContext::getCurrent() ; msg.append(context->getId()); msg.append("\n"); msg.append(e.what()); ERROR("CNc4DataOutput::writeTimeAxis_ (CField* field, \ const boost::shared_ptr cal)", << msg); } } //--------------------------------------------------------------- void CNc4DataOutput::writeTimeAxisAttributes(const StdString & axis_name, const StdString & calendar, const StdString & units, const StdString & time_origin, const StdString & time_bounds, const StdString & standard_name, const StdString & long_name, const StdString & title) { try { SuperClassWriter::addAttribute("standard_name", standard_name, &axis_name); SuperClassWriter::addAttribute("long_name", long_name , &axis_name); SuperClassWriter::addAttribute("title", title , &axis_name); SuperClassWriter::addAttribute("calendar", calendar , &axis_name); SuperClassWriter::addAttribute("units", units , &axis_name); SuperClassWriter::addAttribute("time_origin", time_origin , &axis_name); SuperClassWriter::addAttribute("bounds", time_bounds , &axis_name); } catch (CNetCdfException& e) { StdString msg("On writing time axis Attribute: "); msg.append("In the context : "); CContext* context = CContext::getCurrent() ; msg.append(context->getId()); msg.append("\n"); msg.append(e.what()); ERROR("CNc4DataOutput::writeTimeAxisAttributes(const StdString & axis_name, \ const StdString & calendar,\ const StdString & units, \ const StdString & time_origin, \ const StdString & time_bounds, \ const StdString & standard_name, \ const StdString & long_name, \ const StdString & title)", << msg); } } //--------------------------------------------------------------- void CNc4DataOutput::writeAxisAttributes(const StdString & axis_name, const StdString & axis, const StdString & standard_name, const StdString & long_name, const StdString & units, const StdString & nav_model) { try { SuperClassWriter::addAttribute("axis" , axis , &axis_name); SuperClassWriter::addAttribute("standard_name", standard_name, &axis_name); SuperClassWriter::addAttribute("long_name" , long_name , &axis_name); SuperClassWriter::addAttribute("units" , units , &axis_name); SuperClassWriter::addAttribute("nav_model" , nav_model , &axis_name); } catch (CNetCdfException& e) { StdString msg("On writing Axis Attribute: "); msg.append("In the context : "); CContext* context = CContext::getCurrent() ; msg.append(context->getId()); msg.append("\n"); msg.append(e.what()); ERROR("CNc4DataOutput::writeAxisAttributes(const StdString & axis_name, \ const StdString & axis, \ const StdString & standard_name, \ const StdString & long_name, \ const StdString & units, \ const StdString & nav_model)", << msg); } } //--------------------------------------------------------------- void CNc4DataOutput::writeLocalAttributes (int ibegin, int ni, int jbegin, int nj, StdString domid) { try { SuperClassWriter::addAttribute(StdString("ibegin").append(domid), ibegin); SuperClassWriter::addAttribute(StdString("ni" ).append(domid), ni); SuperClassWriter::addAttribute(StdString("jbegin").append(domid), jbegin); SuperClassWriter::addAttribute(StdString("nj" ).append(domid), nj); } catch (CNetCdfException& e) { StdString msg("On writing Local Attributes: "); msg.append("In the context : "); CContext* context = CContext::getCurrent() ; msg.append(context->getId()); msg.append("\n"); msg.append(e.what()); ERROR("CNc4DataOutput::writeLocalAttributes \ (int ibegin, int ni, int jbegin, int nj, StdString domid)", << msg); } } void CNc4DataOutput::writeLocalAttributes_IOIPSL (int ibegin, int ni, int jbegin, int nj, int ni_glo, int nj_glo, int rank, int size) { CArray array(2) ; try { SuperClassWriter::addAttribute("DOMAIN_number_total",size ) ; SuperClassWriter::addAttribute("DOMAIN_number", rank) ; array=1,2 ; SuperClassWriter::addAttribute("DOMAIN_dimensions_ids",array) ; array=ni_glo,nj_glo ; SuperClassWriter::addAttribute("DOMAIN_size_global", array) ; array=ni,nj ; SuperClassWriter::addAttribute("DOMAIN_size_local", array) ; array=ibegin,jbegin ; SuperClassWriter::addAttribute("DOMAIN_position_first", array) ; array=ibegin+ni-1,jbegin+nj-1 ; SuperClassWriter::addAttribute("DOMAIN_position_last",array) ; array=0,0 ; SuperClassWriter::addAttribute("DOMAIN_halo_size_start", array) ; SuperClassWriter::addAttribute("DOMAIN_halo_size_end", array); SuperClassWriter::addAttribute("DOMAIN_type",string("box")) ; /* SuperClassWriter::addAttribute("DOMAIN_DIM_N001",string("x")) ; SuperClassWriter::addAttribute("DOMAIN_DIM_N002",string("y")) ; SuperClassWriter::addAttribute("DOMAIN_DIM_N003",string("axis_A")) ; SuperClassWriter::addAttribute("DOMAIN_DIM_N004",string("time_counter")) ; */ } catch (CNetCdfException& e) { StdString msg("On writing Local Attributes IOI PSL \n"); msg.append("In the context : "); CContext* context = CContext::getCurrent() ; msg.append(context->getId()); msg.append("\n"); msg.append(e.what()); ERROR("CNc4DataOutput::writeLocalAttributes_IOIPSL \ (int ibegin, int ni, int jbegin, int nj, int ni_glo, int nj_glo, int rank, int size)", << msg); } } //--------------------------------------------------------------- void CNc4DataOutput:: writeFileAttributes(const StdString & name, const StdString & description, const StdString & conventions, const StdString & production, const StdString & timeStamp) { try { SuperClassWriter::addAttribute("name" , name); SuperClassWriter::addAttribute("description", description); SuperClassWriter::addAttribute("conventions", conventions); SuperClassWriter::addAttribute("production" , production); SuperClassWriter::addAttribute("timeStamp" , timeStamp); } catch (CNetCdfException& e) { StdString msg("On writing File Attributes \n "); msg.append("In the context : "); CContext* context = CContext::getCurrent() ; msg.append(context->getId()); msg.append("\n"); msg.append(e.what()); ERROR("CNc4DataOutput:: writeFileAttributes(const StdString & name, \ const StdString & description, \ const StdString & conventions, \ const StdString & production, \ const StdString & timeStamp)", << msg); } } //--------------------------------------------------------------- void CNc4DataOutput::writeMaskAttributes(const StdString & mask_name, int data_dim, int data_ni, int data_nj, int data_ibegin, int data_jbegin) { try { SuperClassWriter::addAttribute("data_dim" , data_dim , &mask_name); SuperClassWriter::addAttribute("data_ni" , data_ni , &mask_name); SuperClassWriter::addAttribute("data_nj" , data_nj , &mask_name); SuperClassWriter::addAttribute("data_ibegin", data_ibegin, &mask_name); SuperClassWriter::addAttribute("data_jbegin", data_jbegin, &mask_name); } catch (CNetCdfException& e) { StdString msg("On writing Mask Attributes \n "); msg.append("In the context : "); CContext* context = CContext::getCurrent() ; msg.append(context->getId()); msg.append("\n"); msg.append(e.what()); ERROR("CNc4DataOutput::writeMaskAttributes(const StdString & mask_name, \ int data_dim, \ int data_ni, \ int data_nj, \ int data_ibegin, \ int data_jbegin)", << msg); } } ///-------------------------------------------------------------- } // namespace xios