# Using RegionTrees adaptivesampling! with MappedArrays

**URL:** <https://discourse.julialang.org/t/using-regiontrees-adaptivesampling-with-mappedarrays/58477>\
**Category:** General Usage\
**Tags:** geo\
**Created:** [April 3, 2021, 1:32am UTC](https://discourse.julialang.org/t/using-regiontrees-adaptivesampling-with-mappedarrays/58477 "2021-04-03T01:32:40Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![Crghilardi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/crghilardi/32/3738_2.png) [@Crghilardi](https://discourse.julialang.org/u/Crghilardi)\
**Post date:** [April 3, 2021, 1:32am UTC](https://discourse.julialang.org/t/using-regiontrees-adaptivesampling-with-mappedarrays/58477/1 "2021-04-03T01:32:40Z")

</div>

I’m playing around with [RegionTrees](https://github.com/rdeits/RegionTrees.jl) and am trying to write a refinery that makes an octree given a bunch of points. The twist being my points are in a [MappedArray](https://github.com/JuliaArrays/MappedArrays.jl). I can populate an initial `Cell` with the `MappedArray` data playload successfully, but then when I try to build a refinery like in the [demo](https://github.com/rdeits/RegionTrees.jl/blob/master/examples/demo/demo.ipynb) it fails.

The stacktrace points to a convert method issue, but it seems strange to me that I can even create the root `Cell` in the first place. What is the missing definition that I would need to define to make this work?

MWE:

```julia
#set up 
using MappedArrays, RegionTrees, StaticArrays
import RegionTrees: AbstractRefinery, needs_refinement, refine_data

a = [rand(100000:200000,3) for i in 1:100]

f = (x -> x * 0.1)
f_inv = (x -> x / 0.1)

m1 = mappedarray(f, f_inv, a)

xmin = minimum(getindex.(m1,1))
ymin = minimum(getindex.(m1,2))
zmin = minimum(getindex.(m1,3))
xmax = maximum(getindex.(m1,1))
ymax = maximum(getindex.(m1,2))
zmax = maximum(getindex.(m1,3))

#this works
root = Cell(SVector(xmin, ymin, zmin), SVector((xmax - xmin), (ymax - ymin), (zmax - zmin)), m1)

#double check to see what it looks like
root.data

#split until each cell contains less than some number of records
struct MyRefinery <: AbstractRefinery
    pointcount::Int64
end

# These two methods are all we need to implement
function needs_refinement(r::MyRefinery, cell)
    length(cell.data) > r.pointcount
end

function refine_data(r::MyRefinery, cell::Cell, indices)
    boundary = child_boundary(cell, indices)
    cell.data[cell.data .< Ref(boundary.widths)]
end

r = MyRefinery(10)

#this errors
adaptivesampling!(root, r)

julia> adaptivesampling!(root, r)
ERROR: MethodError: Cannot `convert` an object of type 
  Cell{Vector{Vector{Float64}},3,Float64{},8} to an object of type 
  Cell{MappedArray{Vector{Float64}, 1, Vector{Vector{Int64}}, var"#3#4", var"#5#6"},3,Float64{},8}
Closest candidates are:
  convert(::Type{T}, ::T) where T at essentials.jl:205
  Cell{Data, N, T, L}(::Any, ::Any, ::Any, ::Any, ::Any) where {Data, N, T, L} at /home/crgxcf/.julia/packages/RegionTrees/rosFd/src/cell.jl:2
Stacktrace:
  [1] cvt1
    @ ./essentials.jl:322 [inlined]
  [2] macro expansion
    @ ./ntuple.jl:74 [inlined]
  [3] ntuple
    @ ./ntuple.jl:69 [inlined]
  [4] convert(#unused#::Type{NTuple{8, Cell{MappedArray{Vector{Float64}, 1, Vector{Vector{Int64}}, var"#3#4", var"#5#6"}, 3, Float64, 8}}}, x::NTuple{8, Cell{Vector{Vector{Float64}}, 3, Float64, 8}})
    @ Base ./essentials.jl:323
  [5] RegionTrees.TwosArray{3, Cell{MappedArray{Vector{Float64}, 1, Vector{Vector{Int64}}, var"#3#4", var"#5#6"}, 3, Float64, 8}, 8}(data::NTuple{8, Cell{Vector{Vector{Float64}}, 3, Float64, 8}})
    @ RegionTrees ~/.julia/packages/RegionTrees/rosFd/src/twosarray.jl:8
  [6] convert
    @ ~/.julia/packages/StaticArrays/rdb0l/src/convert.jl:10 [inlined]
  [7] convert(#unused#::Type{Union{Nothing, RegionTrees.TwosArray{3, Cell{MappedArray{Vector{Float64}, 1, Vector{Vector{Int64}}, var"#3#4", var"#5#6"}, 3, Float64, 8}, 8}}}, x::RegionTrees.TwosArray{3, Cell{Vector{Vector{Float64}}, 3, Float64, 8}, 8})
    @ Base ./some.jl:36
  [8] setproperty!(x::Cell{MappedArray{Vector{Float64}, 1, Vector{Vector{Int64}}, var"#3#4", var"#5#6"}, 3, Float64, 8}, f::Symbol, v::RegionTrees.TwosArray{3, Cell{Vector{Vector{Float64}}, 3, Float64, 8}, 8})
    @ Base ./Base.jl:34
  [9] macro expansion
    @ ~/.julia/packages/RegionTrees/rosFd/src/cell.jl:77 [inlined]
 [10] split!(cell::Cell{MappedArray{Vector{Float64}, 1, Vector{Vector{Int64}}, var"#3#4", var"#5#6"}, 3, Float64, 8}, child_data::RegionTrees.TwosArray{3, Vector{Vector{Float64}}, 8})
    @ RegionTrees ~/.julia/packages/RegionTrees/rosFd/src/cell.jl:65
 [11] split!(cell::Cell{MappedArray{Vector{Float64}, 1, Vector{Vector{Int64}}, var"#3#4", var"#5#6"}, 3, Float64, 8}, child_data_function::Function)
    @ RegionTrees ~/.julia/packages/RegionTrees/rosFd/src/cell.jl:69
 [12] adaptivesampling!(root::Cell{MappedArray{Vector{Float64}, 1, Vector{Vector{Int64}}, var"#3#4", var"#5#6"}, 3, Float64, 8}, refinery::MyRefinery)
    @ RegionTrees ~/.julia/packages/RegionTrees/rosFd/src/adaptivesampling.jl:13
 [13] top-level scope
    @ REPL[28]:1

```

I am able to get around this if I first `collect` the array but then I lose my transform information.

```julia
m2 = collect(m1)
root2 = Cell(SVector(xmin, ymin, zmin), SVector((xmax - xmin), (ymax - ymin), (zmax - zmin)), m2)
#this works
adaptivesampling!(root2, r)

#look at cells
root2.children

```
