Repository: yt-project/yt

Issue:
Runtime error when trying to access `grid_indices` for Ramses data
### Bug report

**Bug summary**

When trying to access the `grid_indices` field on some Ramses data using a sphere region, I get a RuntimeError

**Code for reproduction**

```python
import yt

ds = yt.load('output_00080/info_00080.txt')
sp = ds.sphere([0.2]*3, 0.015)  # This works
print(sp['grid_indices'])

sp = ds.sphere([0.2]*3, 0.015)  # This does not
print(sp['grid_indices'])  # fails
```

**Actual outcome**

```
[1. 1. 1. 1.] dimensionless
Traceback (most recent call last):
  File "/home/ccc/Documents/prog/yt/yt/data_objects/data_containers.py", line 308, in _generate_fluid_field
    finfo.check_available(gen_obj)
  File "/home/ccc/Documents/prog/yt/yt/fields/derived_field.py", line 204, in check_available
    validator(data)
  File "/home/ccc/Documents/prog/yt/yt/fields/derived_field.py", line 470, in __call__
    raise NeedsGridType(self.ghost_zones,self.fields)
yt.fields.field_exceptions.NeedsGridType: (0, None)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/tmp/foo.py", line 9, in <module>
    print(sp['grid_indices'])
  File "/home/ccc/Documents/prog/yt/yt/data_objects/data_containers.py", line 255, in __getitem__
    self.get_data(f)
  File "/home/ccc/Documents/prog/yt/yt/data_objects/data_containers.py", line 1382, in get_data
    self._generate_fields(fields_to_generate)
  File "/home/ccc/Documents/prog/yt/yt/data_objects/data_containers.py", line 1402, in _generate_fields
    fd = self._generate_field(field)
  File "/home/ccc/Documents/prog/yt/yt/data_objects/data_containers.py", line 292, in _generate_field
    tr = self._generate_fluid_field(field)
  File "/home/ccc/Documents/prog/yt/yt/data_objects/data_containers.py", line 310, in _generate_fluid_field
    rv = self._generate_spatial_fluid(field, ngt_exception.ghost_zones)
  File "/home/ccc/Documents/prog/yt/yt/data_objects/data_containers.py", line 330, in _generate_spatial_fluid
    ind += o.select(self.selector, self[field], rv, ind)
  File "/home/ccc/Documents/prog/yt/yt/data_objects/data_containers.py", line 255, in __getitem__
    self.get_data(f)
  File "/home/ccc/Documents/prog/yt/yt/data_objects/data_containers.py", line 1382, in get_data
    self._generate_fields(fields_to_generate)
  File "/home/ccc/Documents/prog/yt/yt/data_objects/data_containers.py", line 1402, in _generate_fields
    fd = self._generate_field(field)
  File "/home/ccc/Documents/prog/yt/yt/data_objects/data_containers.py", line 292, in _generate_field
    tr = self._generate_fluid_field(field)
  File "/home/ccc/Documents/prog/yt/yt/data_objects/data_containers.py", line 312, in _generate_fluid_field
    rv = finfo(gen_obj)
  File "/home/ccc/Documents/prog/yt/yt/fields/derived_field.py", line 256, in __call__
    dd = self._function(self, data)
  File "/home/ccc/Documents/prog/yt/yt/fields/geometric_fields.py", line 76, in _grid_indices
    return data._reshape_vals(arr)
  File "/home/ccc/Documents/prog/yt/yt/data_objects/octree_subset.py", line 102, in _reshape_vals
    raise RuntimeError
RuntimeError
```

This is probably due to the selected region being too small, so that there's only a single cell in it.


Discussion:
I'm trying to see if it's enough to replace in `octree_subset.py:_reshape_vals` by

```python
    def _reshape_vals(self, arr):
        nz = self.nz
        if len(arr.shape) <= 2:
            n_oct = arr.shape[0] // (nz**3)
        elif arr.shape[-1] == 3:
            n_oct = arr.shape[-2]
        else:
            n_oct = arr.shape[-1]
        if arr.size == nz*nz*nz*n_oct:
            new_shape = (nz, nz, nz, n_oct)
        elif arr.size == nz*nz*nz*n_oct * 3:
            new_shape = (nz, nz, nz, n_oct, 3)
        else:
            raise RuntimeError
        # Note that if arr is already F-contiguous, this *shouldn't* copy the
        # data.  But, it might.  However, I can't seem to figure out how to
        # make the assignment to .shape, which *won't* copy the data, make the
        # resultant array viewed in Fortran order.
        arr = arr.reshape(new_shape, order="F")
        return arr
```

Resolving patch:
diff --git a/yt/data_objects/octree_subset.py b/yt/data_objects/octree_subset.py
--- a/yt/data_objects/octree_subset.py
+++ b/yt/data_objects/octree_subset.py
@@ -92,8 +92,10 @@ def _reshape_vals(self, arr):
         nz = self.nz
         if len(arr.shape) <= 2:
             n_oct = arr.shape[0] // (nz**3)
+        elif arr.shape[-1] == 3:
+            n_oct = arr.shape[-2]
         else:
-            n_oct = max(arr.shape)
+            n_oct = arr.shape[-1]
         if arr.size == nz*nz*nz*n_oct:
             new_shape = (nz, nz, nz, n_oct)
         elif arr.size == nz*nz*nz*n_oct * 3:


Test patch: