diff --git a/libcdi b/libcdi index 44f985e1c427d75c261d25e782e895224ccd5a31..c59834a769ba989e8b4f3b6b762ca09d340bfa7a 160000 --- a/libcdi +++ b/libcdi @@ -1 +1 @@ -Subproject commit 44f985e1c427d75c261d25e782e895224ccd5a31 +Subproject commit c59834a769ba989e8b4f3b6b762ca09d340bfa7a diff --git a/src/Remapgrid.cc b/src/Remapgrid.cc index 6cf2c4929b21fb50009da17dffffc99d20440701..0268337596ff4db42df4adfa8cf3c5b7422386d3 100644 --- a/src/Remapgrid.cc +++ b/src/Remapgrid.cc @@ -196,14 +196,12 @@ remap_set_fracmin(double fracMin, Field &field, const RemapGrid *tgtGrid) } static void -remap_field(const RemapSwitches &remapSwitches, RemapType &remap, const Field &field1, Field &field2) +remap_field(RemapMethod mapType, const KnnParams &knnParams, RemapType &remap, const Field &field1, Field &field2) { - auto mapType = remapSwitches.mapType; - auto numNeighbors = remapSwitches.numNeighbors; // clang-format off if (mapType == RemapMethod::BILINEAR) remap_bilinear(remap.search, field1, field2); else if (mapType == RemapMethod::BICUBIC) remap_bicubic(remap.search, field1, field2); - else if (mapType == RemapMethod::KNN) remap_knn(numNeighbors, remap.search, field1, field2); + else if (mapType == RemapMethod::KNN) remap_knn(knnParams, remap.search, field1, field2); else if (mapType == RemapMethod::CONSERV) remap_conserv(remap.vars.normOpt, remap.search, field1, field2); // clang-format on } @@ -507,7 +505,13 @@ public: if (remapSwitches.mapType == RemapMethod::KNN) { if (numNeighbors) remapSwitches.numNeighbors = numNeighbors; - if (remapSwitches.numNeighbors == -1) remapSwitches.numNeighbors = 1; + if (remapSwitches.numNeighbors != -1) + { + knnParams.k = remapSwitches.numNeighbors; + knnParams.kMin = 1; + knnParams.extrapolate = remapExtrapolate; + knnParams.weighted = WeightingMethod::distanceWeighted; + } } } @@ -610,7 +614,7 @@ public: // initialize some remapping variables remap_vars_init(mapType, remapOrder, remap.vars); - remap_print_info(operfunc, remap_genweights, remap.srcGrid, remap.tgtGrid, numMissVals1, remapSwitches.numNeighbors); + remap_print_info(operfunc, remap_genweights, remap.srcGrid, remap.tgtGrid, numMissVals1, knnParams.k); if (remap_genweights) { @@ -620,7 +624,7 @@ public: cdo_abort("Second order remapping is not available for unstructured grids!"); } - remap_gen_weights(remapSwitches, remap); + remap_gen_weights(remapSwitches.mapType, knnParams, remap); } } @@ -699,7 +703,7 @@ public: else remap_field(field2, var.missval, gridsize2, remap.vars, field1, gradients); } - else { remap_field(remapSwitches, remap, field1, field2); } + else { remap_field(remapSwitches.mapType, knnParams, remap, field1, field2); } if (operfunc == REMAPCON || operfunc == REMAPYCON2) { diff --git a/src/Remapweights.cc b/src/Remapweights.cc index 1978b9406d6630353057eab80a1626642554ad6a..532395258e00b049182582726521bfe4f8c9298e 100644 --- a/src/Remapweights.cc +++ b/src/Remapweights.cc @@ -96,6 +96,7 @@ public: }; inline static RegisterEntry<Remapweights> registration = RegisterEntry<Remapweights>(module); + KnnParams knnParams; RemapSwitches remapSwitches; int numRemaps{ 0 }; int numNeighbors{ 0 }; @@ -182,6 +183,13 @@ public: remapSwitches = remap_operfunc_to_maptype(operfunc); if (numNeighbors) remapSwitches.numNeighbors = numNeighbors; + if (remapSwitches.numNeighbors != -1) + { + knnParams.k = remapSwitches.numNeighbors; + knnParams.kMin = 1; + knnParams.extrapolate = remapExtrapolate; + knnParams.weighted = WeightingMethod::distanceWeighted; + } mapType = remapSwitches.mapType; remapOrder = remapSwitches.remapOrder; @@ -275,14 +283,14 @@ public: // initialize some remapping variables remap_vars_init(mapType, remapOrder, remap.vars); - remap_print_info(operfunc, remap_genweights, remap.srcGrid, remap.tgtGrid, numMissVals1, remapSwitches.numNeighbors); + remap_print_info(operfunc, remap_genweights, remap.srcGrid, remap.tgtGrid, numMissVals1, knnParams.k); if (needGradients && remap.srcGrid.rank != 2 && remapOrder == 2) { cdo_abort("Second order remapping is not available for unstructured grids!"); } - remap_gen_weights(remapSwitches, remap); + remap_gen_weights(remapSwitches.mapType, knnParams, remap); std::string outFile = cdo_get_stream_name(1); if (remapDefaults.genMultiWeights) { outFile += string_format("%05d", numRemaps) + ".nc"; } diff --git a/src/remap.h b/src/remap.h index 95c3e99782d471eb7a452e9b4da926be9de44603..1392bc1e6c12928f4ac36a7cb4e12e695dad9dae 100644 --- a/src/remap.h +++ b/src/remap.h @@ -87,12 +87,12 @@ size_t remap_search_cells(RemapSearch &rsearch, bool isReg2dCell, GridCell &grid void remap_bilinear_weights(RemapSearch &rsearch, RemapVars &rv); void remap_bicubic_weights(RemapSearch &rsearch, RemapVars &rv); -void remap_knn_weights(size_t numNeighbors, RemapSearch &rsearch, RemapVars &rv); +void remap_knn_weights(const KnnParams &knnParams, RemapSearch &rsearch, RemapVars &rv); void remap_conserv_weights(RemapSearch &rsearch, RemapVars &rv); void remap_bilinear(RemapSearch &rsearch, const Field &field1, Field &field2); void remap_bicubic(RemapSearch &rsearch, const Field &field1, Field &field2); -void remap_knn(size_t numNeighbors, RemapSearch &rsearch, const Field &field1, Field &field2); +void remap_knn(const KnnParams &knnParams, RemapSearch &rsearch, const Field &field1, Field &field2); void remap_conserv(NormOpt normOpt, RemapSearch &rsearch, const Field &field1, Field &field2); namespace remap diff --git a/src/remap_knn.cc b/src/remap_knn.cc index 7a995d846a71681923bcd032457db95e1f8830dc..cc8ada829f7cdf2964f14af1e9a3755c21e8fca9 100644 --- a/src/remap_knn.cc +++ b/src/remap_knn.cc @@ -21,7 +21,7 @@ // This routine computes the weights for a k-nearest-neighbor interpolation // ----------------------------------------------------------------------- void -remap_knn_weights(size_t numNeighbors, RemapSearch &rsearch, RemapVars &rv) +remap_knn_weights(const KnnParams &knnParams, RemapSearch &rsearch, RemapVars &rv) { auto srcGrid = rsearch.srcGrid; auto tgtGrid = rsearch.tgtGrid; @@ -35,11 +35,11 @@ remap_knn_weights(size_t numNeighbors, RemapSearch &rsearch, RemapVars &rv) auto tgtGridSize = tgtGrid->size; std::vector<WeightLinks> weightLinks(tgtGridSize); - weight_links_alloc(numNeighbors, tgtGridSize, weightLinks); + weight_links_alloc(knnParams.k, tgtGridSize, weightLinks); std::vector<KnnData> knnDataList; knnDataList.reserve(Threading::ompNumThreads); - for (int i = 0; i < Threading::ompNumThreads; ++i) knnDataList.push_back(KnnData(numNeighbors)); + for (int i = 0; i < Threading::ompNumThreads; ++i) knnDataList.push_back(KnnData(knnParams)); cdo::timer timer; @@ -75,7 +75,7 @@ remap_knn_weights(size_t numNeighbors, RemapSearch &rsearch, RemapVars &rv) // Store the link store_weightlinks(0, numWeights, knnData.m_indices.data(), knnData.m_dist.data(), tgtCellIndex, weightLinks); - if (numNeighbors > 1 && numWeights > 0) + if (knnParams.k > 1 && numWeights > 0) { if (numLinksPerValue == -1) numLinksPerValue = numWeights; @@ -86,7 +86,7 @@ remap_knn_weights(size_t numNeighbors, RemapSearch &rsearch, RemapVars &rv) weight_links_to_remap_links(0, tgtGridSize, weightLinks, rv); - if (numNeighbors == 1) + if (knnParams.k == 1) rv.numLinksPerValue = 1; else if (numLinksPerValue > 0) rv.numLinksPerValue = numLinksPerValue; @@ -99,7 +99,7 @@ remap_knn_weights(size_t numNeighbors, RemapSearch &rsearch, RemapVars &rv) // ----------------------------------------------------------------------- template <typename T1, typename T2> static void -remap_knn(const Varray<T1> &srcArray, Varray<T2> &tgtArray, double srcMissval, size_t numMissVals, size_t numNeighbors, +remap_knn(const Varray<T1> &srcArray, Varray<T2> &tgtArray, double srcMissval, size_t numMissVals, const KnnParams &knnParams, RemapSearch &rsearch) { T1 missval = srcMissval; @@ -120,7 +120,7 @@ remap_knn(const Varray<T1> &srcArray, Varray<T2> &tgtArray, double srcMissval, s std::vector<KnnData> knnDataList; knnDataList.reserve(Threading::ompNumThreads); - for (int i = 0; i < Threading::ompNumThreads; ++i) knnDataList.push_back(KnnData(numNeighbors)); + for (int i = 0; i < Threading::ompNumThreads; ++i) knnDataList.push_back(KnnData(knnParams)); cdo::timer timer; @@ -157,10 +157,10 @@ remap_knn(const Varray<T1> &srcArray, Varray<T2> &tgtArray, double srcMissval, s } // remap_knn void -remap_knn(size_t numNeighbors, RemapSearch &remapSearch, const Field &field1, Field &field2) +remap_knn(const KnnParams &knnParams, RemapSearch &remapSearch, const Field &field1, Field &field2) { auto func = [&](const auto &v1, auto &v2, double missval, size_t numMissVals) { - remap_knn(v1, v2, missval, numMissVals, numNeighbors, remapSearch); + remap_knn(v1, v2, missval, numMissVals, knnParams, remapSearch); }; field_operation2(func, field1, field2, field1.missval, field1.numMissVals); } diff --git a/src/remap_utils.cc b/src/remap_utils.cc index ec4b96458f47510b2c9cf426c80a2c82874b7c37..4bfcb6f802e7d14138c4446489bd1371f28e1889 100644 --- a/src/remap_utils.cc +++ b/src/remap_utils.cc @@ -254,14 +254,12 @@ remap_get_normOpt(void) } void -remap_gen_weights(const RemapSwitches &remapSwitches, RemapType &remap) +remap_gen_weights(RemapMethod mapType, const KnnParams &knnParams, RemapType &remap) { - auto mapType = remapSwitches.mapType; - auto numNeighbors = remapSwitches.numNeighbors; // clang-format off if (mapType == RemapMethod::BILINEAR) remap_bilinear_weights(remap.search, remap.vars); else if (mapType == RemapMethod::BICUBIC) remap_bicubic_weights(remap.search, remap.vars); - else if (mapType == RemapMethod::KNN) remap_knn_weights(numNeighbors, remap.search, remap.vars); + else if (mapType == RemapMethod::KNN) remap_knn_weights(knnParams, remap.search, remap.vars); else if (mapType == RemapMethod::CONSERV) remap_conserv_weights(remap.search, remap.vars); // clang-format on } diff --git a/src/remap_utils.h b/src/remap_utils.h index a34fd77eb4a23012a7c6072027200293e501ea68..2f46c11c18bc614dcf6b8ece510f8b5082553a8a 100644 --- a/src/remap_utils.h +++ b/src/remap_utils.h @@ -57,7 +57,7 @@ RemapSwitches remap_operfunc_to_maptype(int operfunc); NormOpt remap_get_normOpt(void); -void remap_gen_weights(const RemapSwitches &remapSwitches, RemapType &remap); +void remap_gen_weights(RemapMethod mapType, const KnnParams &knnParams, RemapType &remap); std::vector<bool> remap_set_grids(int vlistID, const VarList &varList);