@@ -984,52 +984,21 @@ class Dataset {
984984 return absl::OkStatus ();
985985 }
986986
987- // nlohmann::json transform_to_json(const tensorstore::IndexTransform<>& transform) {
988- // nlohmann::json j;
989- // j["input_inclusive_min"] = std::vector<Index>(transform.input_origin().begin(), transform.input_origin().end());
990- // j["input_shape"] = std::vector<Index>(transform.input_shape().begin(), transform.input_shape().end());
991-
992- // // Serialize each output‐index map:
993- // j["output"] = nlohmann::json::array();
994- // for (DimensionIndex d = 0; d < transform.output_rank(); ++d) {
995- // const auto& map = transform.output_index_map(d);
996- // nlohmann::json mo;
997- // switch (map.method()) {
998- // case tensorstore::OutputIndexMethod::constant:
999- // mo["method"] = "constant";
1000- // mo["offset"] = map.offset();
1001- // break;
1002-
1003- // case tensorstore::OutputIndexMethod::single_input_dimension:
1004- // mo["method"] = "single_input_dimension";
1005- // mo["input_dimension"] = map.input_dimension(); // no *
1006- // mo["stride"] = map.stride(); // no *
1007- // mo["offset"] = map.offset();
1008- // break;
1009-
1010- // case tensorstore::OutputIndexMethod::array: {
1011- // mo["method"] = "array";
1012- // mo["offset"] = map.offset();
1013- // mo["stride"] = map.stride();
1014- // auto arr = map.index_array(); // ArrayView<const Index,1>
1015- // std::size_t n = static_cast<std::size_t>(arr.shape()[0]);
1016- // const auto* ptr = arr.data();
1017- // std::vector<Index> vec(ptr, ptr + n);
1018- // mo["index_array"] = std::move(vec);
1019- // break;
1020- // }
1021-
1022- // default:
1023- // // e.g. index_range, if you need it
1024- // break;
1025- // }
1026- // j["output"].push_back(std::move(mo));
1027- // }
1028- // return j;
1029- // }
987+ template <typename T>
988+ void _current_position_increment (std::vector<typename Variable<T>::Interval>& positionInterval, const std::vector<typename Variable<T>::Interval>& interval) {
989+ for (std::size_t d = positionInterval.size (); d-- > 0 ; ) {
990+ if (positionInterval[d].inclusive_min + 1 < interval[d].exclusive_max ) {
991+ ++positionInterval[d].inclusive_min ;
992+ return ;
993+ }
994+ positionInterval[d].inclusive_min = interval[d].inclusive_min ;
995+ }
996+
997+ // Should be unreachable.
998+ }
1030999
10311000 template <typename T>
1032- mdio:: Result<Dataset> where (const mdio:: ValueDescriptor<T>& coord_desc) const {
1001+ Result<Dataset> where (const ValueDescriptor<T>& coord_desc) {
10331002 // 1) Lookup the coordinate Variable<T>
10341003 auto varRes =
10351004 variables.get <T>(std::string (coord_desc.label .label ()));
@@ -1038,82 +1007,44 @@ class Dataset {
10381007 }
10391008 auto var = varRes.value ();
10401009
1041- // auto store = var.get_store();
1042-
1043- // // MDIO_ASSIGN_OR_RETURN(auto transform, tensorstore::GetIndexTransform(store));
1044- // auto transform_res = ApplyIndexTransform(
1045- // [](tensorstore::IndexTransform<> t) { return t; },
1046- // store);
1047- // if (!transform_res.status().ok()) {
1048- // return transform_res.status();
1049- // }
1050- // auto transform = transform_res.value();
1051-
1052- // // std::cout << "transform: " << transform << std::endl;
1053- // auto json = transform_to_json(transform);
1054- // std::cout << json.dump(4) << std::endl;
1055-
1056- MDIO_ASSIGN_OR_RETURN (auto spec, var.get_spec ());
1010+ MDIO_ASSIGN_OR_RETURN (auto interval, var.get_intervals ());
1011+ std::vector<typename Variable<T>::Interval> currentPos; // Hacky, we will use this to track our current position in the dataset.
1012+ for (const auto & i : interval) {
1013+ currentPos.push_back (i);
1014+ }
10571015
1058- std::cout << spec.dump (4 ) << std::endl;
1016+ // 2) Read its data
1017+ auto varFut = var.Read ();
1018+ if (!varFut.status ().ok ()) {
1019+ return varFut.status ();
1020+ }
1021+ auto varDat = varFut.value ();
1022+
1023+ // **Use the flattened data pointer + offset for N‑D arrays:**
1024+ auto * data_ptr = varDat.get_data_accessor ().data ();
1025+ Index offset = varDat.get_flattened_offset ();
1026+ Index nSamples = var.num_samples ();
1027+
1028+ // 3) Collect all flat indices where coord == target value
1029+ std::vector<Index> indices;
1030+ std::vector<RangeDescriptor<Index>> elementwiseSlices;
1031+ for (Index idx = offset; idx < offset + nSamples; ++idx) {
1032+ if (data_ptr[idx] == coord_desc.value ) {
1033+ indices.push_back (idx);
1034+ for (const auto & pos : currentPos) {
1035+ elementwiseSlices.emplace_back (RangeDescriptor<Index>({coord_desc.label .label (), pos.inclusive_min , pos.inclusive_min +1 , 1 }));
1036+ }
1037+ }
1038+ this ->_current_position_increment <T>(currentPos, interval);
1039+ }
10591040
1060- return absl::UnimplementedError (" where() is not yet fully implemented." );
1041+ if (indices.empty ()) {
1042+ return absl::NotFoundError (
1043+ " where(): no entries match coordinate '" +
1044+ std::string (coord_desc.label .label ()) + " '" );
1045+ }
10611046
1062- // 2) Read its data
1063- // auto varFut = var.Read();
1064- // if (!varFut.status().ok()) {
1065- // return varFut.status();
1066- // }
1067- // auto varDat = varFut.value();
1068-
1069- // // **Use the flattened data pointer + offset for N‑D arrays:**
1070- // auto* data_ptr = varDat.get_data_accessor().data();
1071- // Index offset = varDat.get_flattened_offset();
1072- // Index nSamples = var.num_samples();
1073-
1074- // // 3) Collect all flat indices where coord == target value
1075- // std::vector<Index> indices;
1076- // for (Index idx = offset; idx < offset + nSamples; ++idx) {
1077- // if (data_ptr[idx] == coord_desc.value) {
1078- // indices.push_back(idx);
1079- // }
1080- // }
1081- // if (indices.empty()) {
1082- // return absl::NotFoundError(
1083- // "where(): no entries match coordinate '" +
1084- // std::string(coord_desc.label.label()) + "'");
1085- // }
1086-
1087- // // 4) Collapse into contiguous [start,stop) runs
1088- // std::vector<mdio::RangeDescriptor<Index>> runs;
1089- // runs.reserve(4);
1090- // Index run_start = indices[0];
1091- // Index prev = indices[0];
1092-
1093- // for (size_t j = 1; j < indices.size(); ++j) {
1094- // Index cur = indices[j];
1095- // if (cur == prev + 1) {
1096- // prev = cur;
1097- // } else {
1098- // runs.push_back({
1099- // /* label = */ coord_desc.label,
1100- // /* start = */ run_start,
1101- // /* stop = */ prev + 1,
1102- // /* step = */ 1
1103- // });
1104- // run_start = prev = cur;
1105- // }
1106- // }
1107- // // final run
1108- // runs.push_back({
1109- // coord_desc.label,
1110- // run_start,
1111- // prev + 1,
1112- // 1
1113- // });
1114-
1115- // // 5) Apply via your existing isel(...)
1116- // return this->isel(runs);
1047+ return isel (elementwiseSlices);
11171048}
11181049
11191050 /* *
0 commit comments