/*! \file domain_algorithm_reorder.cpp \brief Algorithm for reorder a domain. */ #include "domain_algorithm_reorder.hpp" #include "reorder_domain.hpp" #include "domain.hpp" #include "grid.hpp" #include "grid_transformation_factory_impl.hpp" namespace xios { CGenericAlgorithmTransformation* CDomainAlgorithmReorder::create(bool isSource, CGrid* gridDst, CGrid* gridSrc, CTransformation* transformation, int elementPositionInGrid, std::map& elementPositionInGridSrc2ScalarPosition, std::map& elementPositionInGridSrc2AxisPosition, std::map& elementPositionInGridSrc2DomainPosition, std::map& elementPositionInGridDst2ScalarPosition, std::map& elementPositionInGridDst2AxisPosition, std::map& elementPositionInGridDst2DomainPosition) TRY { std::vector domainListDestP = gridDst->getDomains(); std::vector domainListSrcP = gridSrc->getDomains(); CReorderDomain* reorderDomain = dynamic_cast (transformation); int domainDstIndex = elementPositionInGridDst2DomainPosition[elementPositionInGrid]; int domainSrcIndex = elementPositionInGridSrc2DomainPosition[elementPositionInGrid]; return (new CDomainAlgorithmReorder(isSource, domainListDestP[domainDstIndex], domainListSrcP[domainSrcIndex], reorderDomain)); } CATCH bool CDomainAlgorithmReorder::dummyRegistered_ = CDomainAlgorithmReorder::registerTrans(); bool CDomainAlgorithmReorder::registerTrans() TRY { return CGridTransformationFactory::registerTransformation(TRANS_REORDER_DOMAIN, create); } CATCH CDomainAlgorithmReorder::CDomainAlgorithmReorder(bool isSource, CDomain* domainDestination, CDomain* domainSource, CReorderDomain* reorderDomain) : CAlgorithmTransformationNoDataModification(isSource) TRY { reorderDomain->checkValid(domainSource); domainDestination->type = domainSource->type; domainDestination->ni_glo.setValue(domainSource->ni_glo.getValue()); domainDestination->nj_glo.setValue(domainSource->nj_glo.getValue()); domainDestination->checkAttributes() ; // for now but maybe use domainSource as template for domain destination if (domainDestination->type != CDomain::type_attr::rectilinear) { ERROR("CDomainAlgorithmReorder::CDomainAlgorithmReorder(CDomain* domainDestination, CDomain* domainSource, CReorderDomain* reorderDomain)", << "Domain destination is not rectilinear. This filter work only for rectilinear domain and destination domain with < id = " <getId() <<" > is of type "<type<getId() << std::endl << "Domain destination " <getId() << std::endl); } if (!reorderDomain->invert_lat.isEmpty()) { CArray& j_index=domainDestination->j_index ; int nglo = j_index.numElements() ; int nj_glo =domainDestination->nj_glo ; for (size_t i = 0; i < nglo ; ++i) { j_index(i)=(nj_glo-1)-j_index(i) ; } } if (!reorderDomain->shift_lon_fraction.isEmpty()) { int ni_glo =domainDestination->ni_glo ; int offset = ni_glo*reorderDomain->shift_lon_fraction ; CArray& i_index=domainDestination->i_index ; int nglo = i_index.numElements() ; for (size_t i = 0; i < nglo ; ++i) { i_index(i)= (i_index(i)+offset+ni_glo)%ni_glo ; } } if (!reorderDomain->min_lon.isEmpty() && !reorderDomain->max_lon.isEmpty()) { double min_lon=reorderDomain->min_lon ; double max_lon=reorderDomain->max_lon ; double delta=max_lon-min_lon ; if (!domainDestination->lonvalue_1d.isEmpty() ) { CArray& lon=domainDestination->lonvalue_1d ; for (int i=0;i max_lon) lon(i)=lon(i)-delta ; while (lon(i) < min_lon) lon(i)=lon(i)+delta ; } } if (!domainDestination->bounds_lon_1d.isEmpty() ) { CArray& bounds_lon=domainDestination->bounds_lon_1d ; for (int i=0;i max_lon) bounds_lon(0,i)=bounds_lon(0,i)-delta ; while (bounds_lon(1,i) > max_lon) bounds_lon(1,i)=bounds_lon(1,i)-delta ; while (bounds_lon(0,i) < min_lon) bounds_lon(0,i)=bounds_lon(0,i)+delta ; while (bounds_lon(1,i) < min_lon) bounds_lon(1,i)=bounds_lon(1,i)+delta ; } } } domainDestination->checkAttributes() ; } CATCH }