Repository: yt-project/yt

Issue:
cut_region can't be used to derive angular momentum quantities 
<!--To help us understand and resolve your issue, please fill out the form to
the best of your ability.-->
<!--You can feel free to delete the sections that do not apply.-->

I'm trying to calculate the angular momentum vector of a sphere, and in particular, for the region inside the sphere that has density higher than a certain level. But the result from the cut_region cannot be used to calculate the angular momentum quantity. So here is the code I used for one of the test datasets on yt. 

```python
import yt

ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")

sp = ds.sphere((0.5, 0.5, 0.5), (5, "kpc"))
dense_sp = sp.cut_region(['obj["H_p0_number_density"]>= 1e-2'])
dense_sp.quantities.angular_momentum_vector()
```
This produced the following traceback:

```
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-83-3704089812fe> in <module>
      5 sp = ds.sphere((0.5, 0.5, 0.5), (5, "kpc"))
      6 dense_sp = sp.cut_region(['obj["H_p0_number_density"]>= 1e-2'])
----> 7 dense_sp.quantities.angular_momentum_vector()

~/.local/lib/python3.6/site-packages/yt-3.6.dev0-py3.6-macosx-10.9-x86_64.egg/yt/data_objects/derived_quantities.py in __call__(self, *args, **kwargs)
     67         storage = {}
     68         for sto, ds in parallel_objects(chunks, -1, storage = storage):
---> 69             sto.result = self.process_chunk(ds, *args, **kwargs)
     70         # Now storage will have everything, and will be done via pickling, so
     71         # the units will be preserved.  (Credit to Nathan for this

~/.local/lib/python3.6/site-packages/yt-3.6.dev0-py3.6-macosx-10.9-x86_64.egg/yt/data_objects/derived_quantities.py in process_chunk(self, data, use_gas, use_particles, particle_type)
    493             rvals.extend([(data[self.particle_type, "particle_specific_angular_momentum_%s" % axis] *
    494                            data[self.particle_type, "particle_mass"]).sum(dtype=np.float64) \
--> 495                           for axis in "xyz"])
    496             rvals.append(data[self.particle_type, "particle_mass"].sum(dtype=np.float64))
    497         return rvals

~/.local/lib/python3.6/site-packages/yt-3.6.dev0-py3.6-macosx-10.9-x86_64.egg/yt/data_objects/derived_quantities.py in <listcomp>(.0)
    493             rvals.extend([(data[self.particle_type, "particle_specific_angular_momentum_%s" % axis] *
    494                            data[self.particle_type, "particle_mass"]).sum(dtype=np.float64) \
--> 495                           for axis in "xyz"])
    496             rvals.append(data[self.particle_type, "particle_mass"].sum(dtype=np.float64))
    497         return rvals

~/.local/lib/python3.6/site-packages/yt-3.6.dev0-py3.6-macosx-10.9-x86_64.egg/yt/data_objects/data_containers.py in __getitem__(self, key)
    253                 return self.field_data[f]
    254             else:
--> 255                 self.get_data(f)
    256         # fi.units is the unit expression string. We depend on the registry
    257         # hanging off the dataset to define this unit object.

~/.local/lib/python3.6/site-packages/yt-3.6.dev0-py3.6-macosx-10.9-x86_64.egg/yt/data_objects/selection_data_containers.py in get_data(self, fields)
    901                 parent = getattr(self, "parent", self.base_object)
    902                 self.field_data[field] = \
--> 903                   parent[field][self._part_ind(field[0])]
    904             else:
    905                 self.field_data[field] = self.base_object[field][ind]

~/.local/lib/python3.6/site-packages/yt-3.6.dev0-py3.6-macosx-10.9-x86_64.egg/yt/units/yt_array.py in __getitem__(self, item)
   1056 
   1057     def __getitem__(self, item):
-> 1058         ret = super(YTArray, self).__getitem__(item)
   1059         if ret.shape == ():
   1060             return YTQuantity(ret, self.units, bypass_validation=True)

IndexError: boolean index did not match indexed array along dimension 0; dimension is 44461 but corresponding boolean dimension is 3218
```

**Version Information**
<!--Please specify your platform and versions of the relevant libraries you are
using:-->
  * Operating System: Mac Os High Sierra 10.13.6
  * Python Version: 3.6.6
  * yt version: 3.5.dev0 (installed from source)
  * Other Libraries (if applicable): 

[bug.txt](https://github.com/yt-project/yt/files/2621997/bug.txt)



Discussion:
I can reproduce this, thank you for the report!

Resolving patch:
diff --git a/yt/data_objects/selection_data_containers.py b/yt/data_objects/selection_data_containers.py
--- a/yt/data_objects/selection_data_containers.py
+++ b/yt/data_objects/selection_data_containers.py
@@ -876,7 +876,6 @@ def __init__(self, data_source, conditionals, ds=None,
         self.conditionals = ensure_list(conditionals)
         self.base_object = data_source
         self._selector = None
-        self._particle_mask = {}
         # Need to interpose for __getitem__, fwidth, fcoords, icoords, iwidth,
         # ires and get_data
 
@@ -992,18 +991,14 @@ def _part_ind_brute_force(self, ptype):
         return mask
 
     def _part_ind(self, ptype):
-        if self._particle_mask.get(ptype) is None:
-            # If scipy is installed, use the fast KD tree
-            # implementation. Else, fall back onto the direct
-            # brute-force algorithm.
-            try:
-                _scipy.spatial.KDTree
-                mask = self._part_ind_KDTree(ptype)
-            except ImportError:
-                mask = self._part_ind_brute_force(ptype)
-
-            self._particle_mask[ptype] = mask
-        return self._particle_mask[ptype]
+        # If scipy is installed, use the fast KD tree
+        # implementation. Else, fall back onto the direct
+        # brute-force algorithm.
+        try:
+            _scipy.spatial.KDTree
+            return self._part_ind_KDTree(ptype)
+        except ImportError:
+            return self._part_ind_brute_force(ptype)
 
     @property
     def icoords(self):


Test patch:
diff --git a/yt/data_objects/tests/test_extract_regions.py b/yt/data_objects/tests/test_extract_regions.py
--- a/yt/data_objects/tests/test_extract_regions.py
+++ b/yt/data_objects/tests/test_extract_regions.py
@@ -1,10 +1,12 @@
 import numpy as np
 
+from yt.convenience import load
 from yt.testing import \
     fake_random_ds, \
     fake_amr_ds, \
     assert_equal, \
-    assert_almost_equal
+    assert_almost_equal, \
+    requires_file
 
 def setup():
     from yt.config import ytcfg
@@ -59,3 +61,15 @@ def test_region_and_particles():
 
     assert_equal(expected.shape, result.shape)
     assert_equal(expected, result)
+
+ISOGAL = 'IsolatedGalaxy/galaxy0030/galaxy0030'
+    
+@requires_file(ISOGAL)
+def test_region_chunked_read():
+    # see #2104
+    ds = load("IsolatedGalaxy/galaxy0030/galaxy0030")
+
+    sp = ds.sphere((0.5, 0.5, 0.5), (2, "kpc"))
+    dense_sp = sp.cut_region(['obj["H_p0_number_density"]>= 1e-2'])
+    dense_sp.quantities.angular_momentum_vector()
+